Skip to content

Commit 2353692

Browse files
author
cheon-eunjeong
authored
[톰캣 구현하기 - 1, 2단계] 토리(천은정) 미션 제출합니다. (#364)
* test: File 클래스 학습 테스트 수정 * test: Java I/O Stream 클래스 학습 테스트 수정 * style: 코드 스타일 적용 * feat: 정적 리소스에 대한 응답 기능 구현 * feat: CSS ContentType 지원 기능 구현 * feat: Query String 파싱 기능 구현 * feat: 로그인 여부에 따른 페이지 이동 기능 구현 * feat: 회원 가입 기능 구현 - 기존 로그인 방식 POST로 변경 * feat: Cookie에 JSESSIONID 값 저장 기능 구현 * refactor: Http11Processor 내부 메소드 책임 분리 * feat: Session 구현 * test: 테스트 오류 수정 * sytle: 코드 스타일 수정 * refactor: HttpCookie class 내부 구분자 상수화 * refactor: 입출력 BufferedReader, BufferedWriter로 변경 * refactor: HttpRequestHeader class 내부 구분자 상수화 * refactor: RequestHeader, RequestBody 추출 로직 메서드 분리 * refactor: HttpQuery class 생성 및 Query 추출 로직 메서드 분리 * refactor: 매직넘버 상수화 * refactor: cookie 추출 로직 메서드 분리 * refactor: HttpResponse 생성 로직 책임 분리 * refactor: 불필요한 메서드 제거
1 parent 68db530 commit 2353692

File tree

16 files changed

+748
-121
lines changed

16 files changed

+748
-121
lines changed

study/src/test/java/study/FileTest.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
import org.junit.jupiter.api.DisplayName;
44
import org.junit.jupiter.api.Test;
55

6+
import java.io.IOException;
7+
import java.net.URL;
8+
import java.nio.file.Files;
69
import java.nio.file.Path;
7-
import java.util.Collections;
810
import java.util.List;
911

1012
import static org.assertj.core.api.Assertions.assertThat;
@@ -18,7 +20,7 @@ class FileTest {
1820

1921
/**
2022
* resource 디렉터리 경로 찾기
21-
*
23+
* <p>
2224
* File 객체를 생성하려면 파일의 경로를 알아야 한다.
2325
* 자바 애플리케이션은 resource 디렉터리에 HTML, CSS 같은 정적 파일을 저장한다.
2426
* resource 디렉터리의 경로는 어떻게 알아낼 수 있을까?
@@ -27,27 +29,25 @@ class FileTest {
2729
void resource_디렉터리에_있는_파일의_경로를_찾는다() {
2830
final String fileName = "nextstep.txt";
2931

30-
// todo
31-
final String actual = "";
32+
final ClassLoader classLoader = getClass().getClassLoader();
33+
final URL url = classLoader.getResource(fileName);
34+
final String actual = url.getFile();
3235

3336
assertThat(actual).endsWith(fileName);
3437
}
3538

3639
/**
3740
* 파일 내용 읽기
38-
*
41+
* <p>
3942
* 읽어온 파일의 내용을 I/O Stream을 사용해서 사용자에게 전달 해야 한다.
4043
* File, Files 클래스를 사용하여 파일의 내용을 읽어보자.
4144
*/
4245
@Test
43-
void 파일의_내용을_읽는다() {
46+
void 파일의_내용을_읽는다() throws IOException {
4447
final String fileName = "nextstep.txt";
48+
final String fileUrl = getClass().getClassLoader().getResource(fileName).getFile();
4549

46-
// todo
47-
final Path path = null;
48-
49-
// todo
50-
final List<String> actual = Collections.emptyList();
50+
final List<String> actual = Files.readAllLines(Path.of(fileUrl));
5151

5252
assertThat(actual).containsOnly("nextstep");
5353
}

study/src/test/java/study/IOStreamTest.java

Lines changed: 42 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,30 @@
44
import org.junit.jupiter.api.Nested;
55
import org.junit.jupiter.api.Test;
66

7-
import java.io.*;
7+
import java.io.BufferedInputStream;
8+
import java.io.BufferedOutputStream;
9+
import java.io.BufferedReader;
10+
import java.io.ByteArrayInputStream;
11+
import java.io.ByteArrayOutputStream;
12+
import java.io.FilterInputStream;
13+
import java.io.IOException;
14+
import java.io.InputStream;
15+
import java.io.InputStreamReader;
16+
import java.io.OutputStream;
817

918
import static org.assertj.core.api.Assertions.assertThat;
10-
import static org.mockito.Mockito.*;
19+
import static org.mockito.Mockito.atLeastOnce;
20+
import static org.mockito.Mockito.mock;
21+
import static org.mockito.Mockito.verify;
1122

1223
/**
1324
* 자바는 스트림(Stream)으로부터 I/O를 사용한다.
1425
* 입출력(I/O)은 하나의 시스템에서 다른 시스템으로 데이터를 이동 시킬 때 사용한다.
15-
*
26+
* <p>
1627
* InputStream은 데이터를 읽고, OutputStream은 데이터를 쓴다.
1728
* FilterStream은 InputStream이나 OutputStream에 연결될 수 있다.
1829
* FilterStream은 읽거나 쓰는 데이터를 수정할 때 사용한다. (e.g. 암호화, 압축, 포맷 변환)
19-
*
30+
* <p>
2031
* Stream은 데이터를 바이트로 읽고 쓴다.
2132
* 바이트가 아닌 텍스트(문자)를 읽고 쓰려면 Reader와 Writer 클래스를 연결한다.
2233
* Reader, Writer는 다양한 문자 인코딩(e.g. UTF-8)을 처리할 수 있다.
@@ -26,7 +37,7 @@ class IOStreamTest {
2637

2738
/**
2839
* OutputStream 학습하기
29-
*
40+
* <p>
3041
* 자바의 기본 출력 클래스는 java.io.OutputStream이다.
3142
* OutputStream의 write(int b) 메서드는 기반 메서드이다.
3243
* <code>public abstract void write(int b) throws IOException;</code>
@@ -39,7 +50,7 @@ class OutputStream_학습_테스트 {
3950
* OutputStream의 서브 클래스(subclass)는 특정 매체에 데이터를 쓰기 위해 write(int b) 메서드를 사용한다.
4051
* 예를 들어, FilterOutputStream은 파일로 데이터를 쓸 때,
4152
* 또는 DataOutputStream은 자바의 primitive type data를 다른 매체로 데이터를 쓸 때 사용한다.
42-
*
53+
* <p>
4354
* write 메서드는 데이터를 바이트로 출력하기 때문에 비효율적이다.
4455
* <code>write(byte[] data)</code>와 <code>write(byte b[], int off, int len)</code> 메서드는
4556
* 1바이트 이상을 한 번에 전송 할 수 있어 훨씬 효율적이다.
@@ -48,12 +59,8 @@ class OutputStream_학습_테스트 {
4859
void OutputStream은_데이터를_바이트로_처리한다() throws IOException {
4960
final byte[] bytes = {110, 101, 120, 116, 115, 116, 101, 112};
5061
final OutputStream outputStream = new ByteArrayOutputStream(bytes.length);
51-
52-
/**
53-
* todo
54-
* OutputStream 객체의 write 메서드를 사용해서 테스트를 통과시킨다
55-
*/
56-
62+
63+
outputStream.write(bytes);
5764
final String actual = outputStream.toString();
5865

5966
assertThat(actual).isEqualTo("nextstep");
@@ -63,7 +70,7 @@ class OutputStream_학습_테스트 {
6370
/**
6471
* 효율적인 전송을 위해 스트림에서 버퍼링을 사용 할 수 있다.
6572
* BufferedOutputStream 필터를 연결하면 버퍼링이 가능하다.
66-
*
73+
* <p>
6774
* 버퍼링을 사용하면 OutputStream을 사용할 때 flush를 사용하자.
6875
* flush() 메서드는 버퍼가 아직 가득 차지 않은 상황에서 강제로 버퍼의 내용을 전송한다.
6976
* Stream은 동기(synchronous)로 동작하기 때문에 버퍼가 찰 때까지 기다리면
@@ -73,11 +80,7 @@ class OutputStream_학습_테스트 {
7380
void BufferedOutputStream을_사용하면_버퍼링이_가능하다() throws IOException {
7481
final OutputStream outputStream = mock(BufferedOutputStream.class);
7582

76-
/**
77-
* todo
78-
* flush를 사용해서 테스트를 통과시킨다.
79-
* ByteArrayOutputStream과 어떤 차이가 있을까?
80-
*/
83+
outputStream.flush();
8184

8285
verify(outputStream, atLeastOnce()).flush();
8386
outputStream.close();
@@ -91,24 +94,22 @@ class OutputStream_학습_테스트 {
9194
void OutputStream은_사용하고_나서_close_처리를_해준다() throws IOException {
9295
final OutputStream outputStream = mock(OutputStream.class);
9396

94-
/**
95-
* todo
96-
* try-with-resources를 사용한다.
97-
* java 9 이상에서는 변수를 try-with-resources로 처리할 수 있다.
98-
*/
97+
try (outputStream) {
98+
99+
}
99100

100101
verify(outputStream, atLeastOnce()).close();
101102
}
102103
}
103104

104105
/**
105106
* InputStream 학습하기
106-
*
107+
* <p>
107108
* 자바의 기본 입력 클래스는 java.io.InputStream이다.
108109
* InputStream은 다른 매체로부터 바이트로 데이터를 읽을 때 사용한다.
109110
* InputStream의 read() 메서드는 기반 메서드이다.
110111
* <code>public abstract int read() throws IOException;</code>
111-
*
112+
* <p>
112113
* InputStream의 서브 클래스(subclass)는 특정 매체에 데이터를 읽기 위해 read() 메서드를 사용한다.
113114
*/
114115
@Nested
@@ -124,11 +125,7 @@ class InputStream_학습_테스트 {
124125
byte[] bytes = {-16, -97, -92, -87};
125126
final InputStream inputStream = new ByteArrayInputStream(bytes);
126127

127-
/**
128-
* todo
129-
* inputStream에서 바이트로 반환한 값을 문자열로 어떻게 바꿀까?
130-
*/
131-
final String actual = "";
128+
final String actual = new String(inputStream.readAllBytes());
132129

133130
assertThat(actual).isEqualTo("🤩");
134131
assertThat(inputStream.read()).isEqualTo(-1);
@@ -143,19 +140,17 @@ class InputStream_학습_테스트 {
143140
void InputStream은_사용하고_나서_close_처리를_해준다() throws IOException {
144141
final InputStream inputStream = mock(InputStream.class);
145142

146-
/**
147-
* todo
148-
* try-with-resources를 사용한다.
149-
* java 9 이상에서는 변수를 try-with-resources로 처리할 수 있다.
150-
*/
143+
try (inputStream) {
144+
145+
}
151146

152147
verify(inputStream, atLeastOnce()).close();
153148
}
154149
}
155150

156151
/**
157152
* FilterStream 학습하기
158-
*
153+
* <p>
159154
* 필터는 필터 스트림, reader, writer로 나뉜다.
160155
* 필터는 바이트를 다른 데이터 형식으로 변환 할 때 사용한다.
161156
* reader, writer는 UTF-8, ISO 8859-1 같은 형식으로 인코딩된 텍스트를 처리하는 데 사용된다.
@@ -169,12 +164,12 @@ class FilterStream_학습_테스트 {
169164
* 버퍼 크기를 지정하지 않으면 버퍼의 기본 사이즈는 얼마일까?
170165
*/
171166
@Test
172-
void 필터인_BufferedInputStream를_사용해보자() {
167+
void 필터인_BufferedInputStream를_사용해보자() throws IOException {
173168
final String text = "필터에 연결해보자.";
174169
final InputStream inputStream = new ByteArrayInputStream(text.getBytes());
175-
final InputStream bufferedInputStream = null;
170+
final InputStream bufferedInputStream = new BufferedInputStream(inputStream);
176171

177-
final byte[] actual = new byte[0];
172+
final byte[] actual = bufferedInputStream.readAllBytes();
178173

179174
assertThat(bufferedInputStream).isInstanceOf(FilterInputStream.class);
180175
assertThat(actual).isEqualTo("필터에 연결해보자.".getBytes());
@@ -197,16 +192,23 @@ class InputStreamReader_학습_테스트 {
197192
* 필터인 BufferedReader를 사용하면 readLine 메서드를 사용해서 문자열(String)을 한 줄 씩 읽어올 수 있다.
198193
*/
199194
@Test
200-
void BufferedReader를_사용하여_문자열을_읽어온다() {
195+
void BufferedReader를_사용하여_문자열을_읽어온다() throws IOException {
201196
final String emoji = String.join("\r\n",
202197
"😀😃😄😁😆😅😂🤣🥲☺️😊",
203198
"😇🙂🙃😉😌😍🥰😘😗😙😚",
204199
"😋😛😝😜🤪🤨🧐🤓😎🥸🤩",
205200
"");
206201
final InputStream inputStream = new ByteArrayInputStream(emoji.getBytes());
202+
final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
207203

208204
final StringBuilder actual = new StringBuilder();
209205

206+
String line = bufferedReader.readLine();
207+
while (line != null) {
208+
actual.append(line + "\r\n");
209+
line = bufferedReader.readLine();
210+
}
211+
210212
assertThat(actual).hasToString(emoji);
211213
}
212214
}

0 commit comments

Comments
 (0)