Skip to content

Commit 3219616

Browse files
lkhlkh23javajigi
authored andcommitted
Step2 PR (#40)
* 핸들러 매핑 람다로 구현 * 요구사항 3시작 * 요구사항3 적용완료 * 회원가입 완료 및 Socket Close 해결 * 전체 삭제 이전 임시 백업 * Step1 * MethodType Enum 추가 * list.html Mustache 문법 적용완료 * HandlerArgumehtResolver 적용 * Step2 PR * 충돌 해결시 발생했던 중복 클래스 제거 및 피드백1, 피드백 3 반영 * 피드백 3 반영 * Method 추가 시, 중복적인 로직 제거
1 parent 0d0cbac commit 3219616

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1058
-405
lines changed

src/main/java/db/DataBase.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public class DataBase {
1212

1313
static {
1414
/* 로그인 반복적으로 수행하는 것이 불편해서 테스트 아이디 생성 */
15-
users.put("javajigi", new User("javajigi", "password", "MrPobi", "slipp@naver.com"));
15+
users.put("javajigi", new User("javajigi", "password", "Pobi", "slipp@naver.com"));
1616
}
1717

1818
public static void addUser(User user) {

src/main/java/model/HttpHeader.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package model;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
public class HttpHeader {
7+
8+
private Map<String, String> header;
9+
10+
public HttpHeader() {
11+
header = new HashMap<>();
12+
}
13+
14+
public HttpHeader(Map<String, String> header) {
15+
this.header = header;
16+
}
17+
18+
public void addHeader(String key, String value) {
19+
this.header.put(key, value);
20+
}
21+
22+
public String obtainHeader(String headerName) {
23+
return this.header.get(headerName);
24+
}
25+
26+
public boolean isResource() {
27+
return header.get("Accept").contains("text/css");
28+
}
29+
30+
public int obtainContentLength() {
31+
if(header.containsKey("Content-Length")) {
32+
return Integer.parseInt(header.get("Content-Length"));
33+
}
34+
35+
return 0;
36+
}
37+
38+
}

src/main/java/model/HttpRequest.java

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package model;
2+
3+
import util.HttpRequestUtils;
4+
import util.ParameterConverter;
5+
6+
import java.util.Map;
7+
8+
public class HttpRequest {
9+
10+
private static final String SPLIT_BLANK = " ";
11+
private static final String QUESTION_MARK = "?";
12+
private static final String SPLIT_QUESTION = "\\?";
13+
14+
private Mapping mapping;
15+
private HttpHeader httpHeader;
16+
private Map<String, String> body;
17+
18+
public HttpRequest(String path, MethodType method, String body, HttpHeader httpHeader) {
19+
this.httpHeader = httpHeader;
20+
21+
if(path.contains(QUESTION_MARK)) {
22+
body = path.split(SPLIT_QUESTION)[1];
23+
}
24+
25+
this.body = HttpRequestUtils.parseQueryString(body);
26+
this.mapping = new Mapping(path, method);
27+
}
28+
29+
public Mapping getMapping() {
30+
return mapping;
31+
}
32+
33+
public Map<String, String> getBody() {
34+
return body;
35+
}
36+
37+
public String obtainHeader(String headerName) {
38+
return httpHeader.obtainHeader(headerName);
39+
}
40+
41+
public void addHeader(String headerName, String headerValue) {
42+
httpHeader.addHeader(headerName, headerValue);
43+
}
44+
45+
public boolean isResource() {
46+
return httpHeader.isResource();
47+
}
48+
49+
/*
50+
@param Header의 첫 라인
51+
@return HttpHeader 에서 URL 추출
52+
*/
53+
public static String obtainURL(String line) {
54+
return line.split(SPLIT_BLANK)[1];
55+
}
56+
57+
/*
58+
@param Header의 첫 라인
59+
@return HttpHeader 에서 MethodType 추출
60+
*/
61+
public static MethodType obtainMethod(String line) {
62+
return MethodType.obtainMethodTypeByName(line.split(SPLIT_BLANK)[0]);
63+
}
64+
65+
/*
66+
@param
67+
@return 파라미터의 필드값 반환 (URL Encoding 처리된 문자는 URL Decoding)
68+
*/
69+
public String obtainParamElement(String field) {
70+
if(!body.containsKey(field)) {
71+
return "";
72+
}
73+
return ParameterConverter.urlDecoding(body.get(field));
74+
}
75+
76+
@Override
77+
public String toString() {
78+
return "HttpRequest{" +
79+
"mapping=" + mapping +
80+
", body=" + body +
81+
'}';
82+
}
83+
}

src/main/java/model/HttpResponse.java

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package model;
2+
3+
import org.slf4j.Logger;
4+
5+
import java.io.DataOutputStream;
6+
import java.io.IOException;
7+
import java.util.Arrays;
8+
import java.util.HashMap;
9+
import java.util.Map;
10+
import java.util.function.Consumer;
11+
12+
import static org.slf4j.LoggerFactory.getLogger;
13+
14+
public class HttpResponse {
15+
16+
private static final Logger logger = getLogger(HttpResponse.class);
17+
18+
private byte[] body;
19+
private HttpHeader httpHeader;
20+
private static Map<String, String> statusMapper = new HashMap<>();
21+
private static Map<String, Consumer<DataOutputStream>> statusProcessor = new HashMap<>();
22+
23+
static {
24+
statusMapper.put("200", "OK");
25+
statusMapper.put("302", "FOUND");
26+
}
27+
28+
public HttpResponse(byte[] body) {
29+
this.httpHeader = new HttpHeader();
30+
this.body = body;
31+
32+
initStatusMapper();
33+
}
34+
35+
public void initStatusMapper() {
36+
statusProcessor.put("200", (dos) -> response200Header(dos));
37+
statusProcessor.put("302", (dos) -> response302Header(dos));
38+
}
39+
40+
public byte[] getBody() {
41+
return body;
42+
}
43+
44+
public void setBody(byte[] body) {
45+
this.body = body;
46+
}
47+
48+
public HttpResponse addHeader(String key, String value) {
49+
httpHeader.addHeader(key, value);
50+
return this;
51+
}
52+
53+
/*
54+
@param
55+
@return response에 대한 공통적인 속성을 작성한 템플
56+
*/
57+
public HttpResponse responseHeader(DataOutputStream dos, boolean isResource) throws IOException {
58+
59+
String statusCode = httpHeader.obtainHeader("status");
60+
dos.writeBytes(String.format("HTTP/1.1 %s %s\r\n", statusCode, obtainStatus(statusCode)));
61+
String contentType = "Content-Type: text/html;charset=utf-8\r\n";
62+
if(isResource) {
63+
contentType = "Content-Type: text/css\r\n";
64+
}
65+
dos.writeBytes(contentType);
66+
67+
/* status에 따라 response 구성이 조금씩 다르기 때문에 다른 부분은 람다로 처리 */
68+
statusProcessor.get(statusCode).accept(dos);
69+
dos.writeBytes(String.format("Set-Cookie: %s\r\n", httpHeader.obtainHeader("Set-Cookie")));
70+
dos.writeBytes("\r\n");
71+
72+
return this;
73+
}
74+
75+
public String obtainStatus(String statusCode) {
76+
return statusMapper.get(statusCode);
77+
}
78+
79+
private void response302Header(DataOutputStream dos) {
80+
try {
81+
dos.writeBytes(String.format("Location: %s\r\n", httpHeader.obtainHeader("Location")));
82+
} catch (IOException e) {
83+
e.printStackTrace();
84+
}
85+
}
86+
87+
private void response200Header(DataOutputStream dos) {
88+
try {
89+
dos.writeBytes(String.format("Content-Length: %d\r\n", this.body.length));
90+
} catch (IOException e) {
91+
e.printStackTrace();
92+
}
93+
}
94+
95+
public HttpResponse responseBody(DataOutputStream dos) {
96+
try {
97+
dos.write(this.body, 0, this.body.length);
98+
dos.flush();
99+
} catch (IOException e) {
100+
logger.error(e.getMessage());
101+
e.getStackTrace();
102+
}
103+
return this;
104+
}
105+
106+
@Override
107+
public String toString() {
108+
return "HttpResponse{" +
109+
"body=" + Arrays.toString(body) +
110+
", httpHeader=" + httpHeader +
111+
'}';
112+
}
113+
}

src/main/java/model/Mapping.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44

55
public class Mapping {
66

7-
private static final String RESOURCE_MARK = ".css";
7+
public static final String RESOURCE_MARK = ".css";
8+
public static final String SPLIT_QUESTION = "\\?";
9+
public static final String QUESTION_MARK = "?";
810

9-
private String method;
11+
private MethodType method;
1012
private String path;
1113

12-
public Mapping(String path, String method) {
14+
public Mapping(String path, MethodType method) {
1315
this.method = method;
1416
this.path = path;
1517
}
@@ -22,6 +24,19 @@ public boolean isResource() {
2224
return path.contains(RESOURCE_MARK);
2325
}
2426

27+
public static Mapping of(String path, String method) {
28+
/* GET Method Parameter 존재할 경우에만 동작! */
29+
if(path.contains(QUESTION_MARK)) {
30+
path = initParams(path);
31+
}
32+
33+
return new Mapping(path, MethodType.obtainMethodTypeByName(method));
34+
}
35+
36+
private static String initParams(String path) {
37+
return path.split(SPLIT_QUESTION)[0];
38+
}
39+
2540
@Override
2641
public String toString() {
2742
return "Mapping{" +

src/main/java/model/MethodType.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package model;
2+
3+
import setting.GetMapping;
4+
import setting.PostMapping;
5+
6+
import java.lang.reflect.Method;
7+
8+
public enum MethodType {
9+
10+
GET("GET", GetMapping.class), POST("POST", PostMapping.class), NOT("NOT", null);
11+
12+
private String methodType;
13+
private Class clazz;
14+
15+
MethodType(String methodType, Class clazz) {
16+
this.methodType = methodType;
17+
this.clazz = clazz;
18+
}
19+
20+
public static MethodType obtainMethodTypeByName(String methodName) {
21+
for (MethodType value : values()) {
22+
if(value.methodType.equals(methodName)) {
23+
return value;
24+
}
25+
}
26+
return NOT;
27+
}
28+
29+
public static MethodType obtainMethodTypeByClass(Class clazz) {
30+
for (MethodType value : values()) {
31+
if(value.clazz == clazz) {
32+
return value;
33+
}
34+
}
35+
return NOT;
36+
}
37+
38+
public static Class obtainMethodClass(Method method) {
39+
for (MethodType value : MethodType.values()) {
40+
if(method.getDeclaredAnnotation(value.clazz) != null) {
41+
return value.clazz;
42+
}
43+
}
44+
return NOT.clazz;
45+
}
46+
}

src/main/java/model/RequestEntity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public class RequestEntity {
1717
private Map<String, String> body = new HashMap<>();
1818
private Map<String, String> headerInfo;
1919

20-
public RequestEntity(String path, String method, String body, Map<String, String> headerInfo) {
20+
public RequestEntity(String path, MethodType method, String body, Map<String, String> headerInfo) {
2121
this.headerInfo = headerInfo;
2222

2323
/* POST Method Parameter 존재할 경우에만 동작 */

src/main/java/model/ResponseEntity.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
package model;
22

33
import org.slf4j.Logger;
4-
import webserver.ClientModel;
54

65
import java.io.DataOutputStream;
76
import java.io.IOException;
8-
import java.util.Arrays;
97
import java.util.HashMap;
108
import java.util.Map;
119
import java.util.function.Consumer;

src/main/java/security/ClientSession.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package security;
22

3+
import model.User;
34
import java.util.HashMap;
45
import java.util.Map;
56

@@ -17,6 +18,10 @@ public ClientSession registerSession(Object object) {
1718
return this;
1819
}
1920

21+
public User getLoginUser() {
22+
return (User) session.get(LOGIN_SESSION);
23+
}
24+
2025
public boolean hasSession(String sessionName) {
2126
return session.containsKey(sessionName);
2227
}

src/main/java/security/HttpSession.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package security;
22

3+
import model.User;
34
import java.util.HashMap;
45
import java.util.Map;
56

@@ -42,4 +43,8 @@ public boolean isLoginUser() {
4243
}
4344
return true;
4445
}
46+
47+
public User obtainLoginUser() {
48+
return httpSessions.get(this.jSessionId).getLoginUser();
49+
}
4550
}

0 commit comments

Comments
 (0)