From 7d6889f6e46ee3b476d973a5b0a01554313f2051 Mon Sep 17 00:00:00 2001 From: Senglee Choi Date: Sat, 23 Jul 2022 14:38:49 +0900 Subject: [PATCH 1/3] =?UTF-8?q?=EC=9A=94=EA=B5=AC=EC=82=AC=ED=95=AD=201=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Request, Response 객체를 분리하여 코드 추상화 --- src/main/java/webserver/Request.java | 22 +++++++ src/main/java/webserver/RequestHandler.java | 69 +++++++++++++++------ src/main/java/webserver/Response.java | 26 ++++++++ src/main/java/webserver/ResponseMaker.java | 26 ++++++++ src/main/java/webserver/StatusCode.java | 19 ++++++ 5 files changed, 144 insertions(+), 18 deletions(-) create mode 100644 src/main/java/webserver/Request.java create mode 100644 src/main/java/webserver/Response.java create mode 100644 src/main/java/webserver/ResponseMaker.java create mode 100644 src/main/java/webserver/StatusCode.java diff --git a/src/main/java/webserver/Request.java b/src/main/java/webserver/Request.java new file mode 100644 index 0000000..8df7a42 --- /dev/null +++ b/src/main/java/webserver/Request.java @@ -0,0 +1,22 @@ +package webserver; + +import java.io.BufferedReader; + +public class Request { + private String method; + private String uri; + + public Request(String msg) { + String[] msgArr = msg.split(" "); + method = msgArr[0]; + uri = msgArr[1]; + } + + public String getMethod() { + return method; + } + + public String getUri() { + return uri; + } +} diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index 90195ec..e68000f 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -1,18 +1,22 @@ package webserver; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; +import java.io.*; import java.net.Socket; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.xml.crypto.Data; + public class RequestHandler extends Thread { private static final Logger log = LoggerFactory.getLogger(RequestHandler.class); + private static final ResponseMaker responseMaker = new ResponseMaker(); private Socket connection; + private DataOutputStream dos; + private BufferedReader br; public RequestHandler(Socket connectionSocket) { this.connection = connectionSocket; @@ -22,34 +26,63 @@ public void run() { log.debug("New Client Connect! Connected IP : {}, Port : {}", connection.getInetAddress(), connection.getPort()); + try (InputStream in = connection.getInputStream(); OutputStream out = connection.getOutputStream()) { - // TODO 사용자 요청에 대한 처리는 이 곳에 구현하면 된다. - DataOutputStream dos = new DataOutputStream(out); - byte[] body = "Hello World".getBytes(); - response200Header(dos, body.length); - responseBody(dos, body); + dos = new DataOutputStream(out); + br = new BufferedReader(new InputStreamReader(in)); + + Request request = readRequest(br); + sendResponse(makeResponseOf(request)); + br.close(); + } catch (IOException e) { log.error(e.getMessage()); } } - private void response200Header(DataOutputStream dos, int lengthOfBodyContent) { + public Request readRequest(BufferedReader br) throws IOException { + Request request = new Request(br.readLine()); + log.debug("method: {}, uri: {}", request.getMethod(), request.getUri()); + return request; + } + + public Response makeResponseOf(Request request) { try { - dos.writeBytes("HTTP/1.1 200 OK \r\n"); - dos.writeBytes("Content-Type: text/html;charset=utf-8\r\n"); - dos.writeBytes("Content-Length: " + lengthOfBodyContent + "\r\n"); - dos.writeBytes("\r\n"); + byte[] body = Files.readAllBytes(new File("./webapp" + request.getUri()).toPath()); + return new Response(StatusCode.OK, body); } catch (IOException e) { - log.error(e.getMessage()); + return new Response(StatusCode.OK, "헬로우 월드!".getBytes(StandardCharsets.UTF_8)); } } - private void responseBody(DataOutputStream dos, byte[] body) { + public void sendResponse(Response response) { try { - dos.write(body, 0, body.length); - dos.flush(); + dos.write(response.getHeader()); + dos.write(response.getBody()); } catch (IOException e) { log.error(e.getMessage()); } + } + +// private void response200Header(DataOutputStream dos, int lengthOfBodyContent) { +// try { +// dos.writeBytes("HTTP/1.1 200 OK \r\n"); +// dos.writeBytes("Content-Type: text/html;charset=utf-8\r\n"); +// dos.writeBytes("Content-Length: " + lengthOfBodyContent + "\r\n"); +// dos.writeBytes("\r\n"); +// } catch (IOException e) { +// log.error(e.getMessage()); +// } +// } +// +// +// private void responseBody(DataOutputStream dos, byte[] body) { +// try { +// dos.write(body, 0, body.length); +// dos.flush(); +// } catch (IOException e) { +// log.error(e.getMessage()); +// } +// } } diff --git a/src/main/java/webserver/Response.java b/src/main/java/webserver/Response.java new file mode 100644 index 0000000..5c89a95 --- /dev/null +++ b/src/main/java/webserver/Response.java @@ -0,0 +1,26 @@ +package webserver; + +import java.nio.charset.StandardCharsets; + +public class Response { + private StatusCode statusCode; + private byte[] body; + + public Response(StatusCode statusCode, byte[] body) { + this.statusCode = statusCode; + this.body = body; + } + + public byte[] getHeader() { + StringBuilder sb = new StringBuilder(); + sb.append(String.format("HTTP/1.1 %d %s \r\n", statusCode.getCodeNumber(), statusCode)); + sb.append("Content-Type: text/html;charset=utf-8\r\n"); + sb.append("Content-Length: " + body.length + "\r\n"); + sb.append("\r\n"); + return sb.toString().getBytes(StandardCharsets.UTF_8); + } + + public byte[] getBody() { + return body.clone(); + } +} diff --git a/src/main/java/webserver/ResponseMaker.java b/src/main/java/webserver/ResponseMaker.java new file mode 100644 index 0000000..eae95ba --- /dev/null +++ b/src/main/java/webserver/ResponseMaker.java @@ -0,0 +1,26 @@ +package webserver; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +public class ResponseMaker { + private final Map mapper = new HashMap<>(); + + public ResponseMaker() { + mapper.put("/index.html", "./webapp/index.html"); + } + + public Optional getResponse(Request request) throws IOException { + String path = mapper.get(request.getUri()); + if (Objects.isNull(path)) { + return Optional.empty(); + } + byte[] body = Files.readAllBytes(new File(path).toPath()); + return Optional.of(new Response(StatusCode.OK, body)); + } +} diff --git a/src/main/java/webserver/StatusCode.java b/src/main/java/webserver/StatusCode.java new file mode 100644 index 0000000..7ab56ec --- /dev/null +++ b/src/main/java/webserver/StatusCode.java @@ -0,0 +1,19 @@ +package webserver; + +public enum StatusCode { + OK(200), + REDIRECT(302); + + + private int codeNumber; + + private StatusCode(int codeNumber) { + this.codeNumber = codeNumber; + } + + public int getCodeNumber() { + return codeNumber; + } + + +} From 1fc51703b3230b1edcf546df1aa2ad6a4df69747 Mon Sep 17 00:00:00 2001 From: Senglee Choi Date: Sat, 23 Jul 2022 14:42:15 +0900 Subject: [PATCH 2/3] =?UTF-8?q?response=20=EB=B3=80=EC=88=98=20=EC=A0=95?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/webserver/RequestHandler.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index e68000f..962bf51 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -26,15 +26,15 @@ public void run() { log.debug("New Client Connect! Connected IP : {}, Port : {}", connection.getInetAddress(), connection.getPort()); - try (InputStream in = connection.getInputStream(); OutputStream out = connection.getOutputStream()) { dos = new DataOutputStream(out); br = new BufferedReader(new InputStreamReader(in)); Request request = readRequest(br); - sendResponse(makeResponseOf(request)); - br.close(); + Response response = makeResponseOf(request); + sendResponse(response); + br.close(); } catch (IOException e) { log.error(e.getMessage()); } From 0324ca6f69cab842d0b8a2b87d75fd2edbad559f Mon Sep 17 00:00:00 2001 From: Senglee Choi Date: Sat, 23 Jul 2022 19:01:14 +0900 Subject: [PATCH 3/3] =?UTF-8?q?Feat:=20ResponseMaker=EC=9D=84=20=ED=99=9C?= =?UTF-8?q?=EC=9A=A9=ED=95=9C=20=EB=B9=84=EC=A6=88=EB=8B=88=EC=8A=A4=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=84=B8=EB=B6=84=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ResponseMaker 클래스를 통해 uri에 맞는 세부 비즈니스로직을 적용할 수 있도록 함. --- src/main/java/webserver/Request.java | 22 ------- src/main/java/webserver/RequestHandler.java | 62 ++++++++----------- src/main/java/webserver/ResponseMaker.java | 26 -------- .../logicexecutor/LogicExecutor.java | 8 +++ .../logicexecutor/LoginLogicExecutor.java | 22 +++++++ src/main/java/webserver/request/Request.java | 32 ++++++++++ .../webserver/{ => response}/Response.java | 2 +- .../webserver/response/ResponseMaker.java | 33 ++++++++++ .../webserver/{ => response}/StatusCode.java | 2 +- webapp/user/form.html | 2 +- 10 files changed, 125 insertions(+), 86 deletions(-) delete mode 100644 src/main/java/webserver/Request.java delete mode 100644 src/main/java/webserver/ResponseMaker.java create mode 100644 src/main/java/webserver/logicexecutor/LogicExecutor.java create mode 100644 src/main/java/webserver/logicexecutor/LoginLogicExecutor.java create mode 100644 src/main/java/webserver/request/Request.java rename src/main/java/webserver/{ => response}/Response.java (96%) create mode 100644 src/main/java/webserver/response/ResponseMaker.java rename src/main/java/webserver/{ => response}/StatusCode.java (89%) diff --git a/src/main/java/webserver/Request.java b/src/main/java/webserver/Request.java deleted file mode 100644 index 8df7a42..0000000 --- a/src/main/java/webserver/Request.java +++ /dev/null @@ -1,22 +0,0 @@ -package webserver; - -import java.io.BufferedReader; - -public class Request { - private String method; - private String uri; - - public Request(String msg) { - String[] msgArr = msg.split(" "); - method = msgArr[0]; - uri = msgArr[1]; - } - - public String getMethod() { - return method; - } - - public String getUri() { - return uri; - } -} diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index 962bf51..c3b990c 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -2,13 +2,14 @@ import java.io.*; import java.net.Socket; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; +import java.util.HashMap; +import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -import javax.xml.crypto.Data; +import webserver.request.Request; +import webserver.response.Response; +import webserver.response.ResponseMaker; public class RequestHandler extends Thread { private static final Logger log = LoggerFactory.getLogger(RequestHandler.class); @@ -29,8 +30,7 @@ public void run() { try (InputStream in = connection.getInputStream(); OutputStream out = connection.getOutputStream()) { dos = new DataOutputStream(out); br = new BufferedReader(new InputStreamReader(in)); - - Request request = readRequest(br); + Request request = readRequest(); Response response = makeResponseOf(request); sendResponse(response); @@ -40,19 +40,32 @@ public void run() { } } - public Request readRequest(BufferedReader br) throws IOException { - Request request = new Request(br.readLine()); + public Request readRequest() throws IOException { + String firstLine = br.readLine(); + Request request = new Request(firstLine); + request.setParams(parseParams()); log.debug("method: {}, uri: {}", request.getMethod(), request.getUri()); return request; } - public Response makeResponseOf(Request request) { - try { - byte[] body = Files.readAllBytes(new File("./webapp" + request.getUri()).toPath()); - return new Response(StatusCode.OK, body); - } catch (IOException e) { - return new Response(StatusCode.OK, "헬로우 월드!".getBytes(StandardCharsets.UTF_8)); + private Map parseParams() throws IOException { + Map params = new HashMap<>(); + String line = br.readLine(); + while (line.length() != 0 && !(line.equals("\r\n"))) { + log.debug(line); + line = br.readLine(); } + if (line.length() != 0) { + String[] paramsString = br.readLine().split("&"); + for (String param : paramsString) { + params.put(param.split("=")[0], param.split("=")[1]); + } + } + return params; + } + + public Response makeResponseOf(Request request) { + return responseMaker.getResponse(request); } public void sendResponse(Response response) { @@ -64,25 +77,4 @@ public void sendResponse(Response response) { } } - -// private void response200Header(DataOutputStream dos, int lengthOfBodyContent) { -// try { -// dos.writeBytes("HTTP/1.1 200 OK \r\n"); -// dos.writeBytes("Content-Type: text/html;charset=utf-8\r\n"); -// dos.writeBytes("Content-Length: " + lengthOfBodyContent + "\r\n"); -// dos.writeBytes("\r\n"); -// } catch (IOException e) { -// log.error(e.getMessage()); -// } -// } -// -// -// private void responseBody(DataOutputStream dos, byte[] body) { -// try { -// dos.write(body, 0, body.length); -// dos.flush(); -// } catch (IOException e) { -// log.error(e.getMessage()); -// } -// } } diff --git a/src/main/java/webserver/ResponseMaker.java b/src/main/java/webserver/ResponseMaker.java deleted file mode 100644 index eae95ba..0000000 --- a/src/main/java/webserver/ResponseMaker.java +++ /dev/null @@ -1,26 +0,0 @@ -package webserver; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; - -public class ResponseMaker { - private final Map mapper = new HashMap<>(); - - public ResponseMaker() { - mapper.put("/index.html", "./webapp/index.html"); - } - - public Optional getResponse(Request request) throws IOException { - String path = mapper.get(request.getUri()); - if (Objects.isNull(path)) { - return Optional.empty(); - } - byte[] body = Files.readAllBytes(new File(path).toPath()); - return Optional.of(new Response(StatusCode.OK, body)); - } -} diff --git a/src/main/java/webserver/logicexecutor/LogicExecutor.java b/src/main/java/webserver/logicexecutor/LogicExecutor.java new file mode 100644 index 0000000..51a3e96 --- /dev/null +++ b/src/main/java/webserver/logicexecutor/LogicExecutor.java @@ -0,0 +1,8 @@ +package webserver.logicexecutor; + +import webserver.request.Request; +import webserver.response.Response; + +public interface LogicExecutor { + Response run(Request request); +} diff --git a/src/main/java/webserver/logicexecutor/LoginLogicExecutor.java b/src/main/java/webserver/logicexecutor/LoginLogicExecutor.java new file mode 100644 index 0000000..70d4cf5 --- /dev/null +++ b/src/main/java/webserver/logicexecutor/LoginLogicExecutor.java @@ -0,0 +1,22 @@ +package webserver.logicexecutor; + +import model.User; +import webserver.request.Request; +import webserver.response.Response; +import webserver.response.StatusCode; + +import java.nio.charset.StandardCharsets; +import java.util.Map; + +public class LoginLogicExecutor implements LogicExecutor{ + @Override + public Response run(Request request) { + Map params = request.getParams(); + String userId = params.get("userId"); + String password = params.get("password"); + String name = params.get("name"); + String email = params.get("email"); + User user = new User(userId, password, name, email); + return new Response(StatusCode.OK, user.toString().getBytes(StandardCharsets.UTF_8)); + } +} diff --git a/src/main/java/webserver/request/Request.java b/src/main/java/webserver/request/Request.java new file mode 100644 index 0000000..44e3cb0 --- /dev/null +++ b/src/main/java/webserver/request/Request.java @@ -0,0 +1,32 @@ +package webserver.request; + +import java.io.BufferedReader; +import java.util.Map; + +public class Request { + private String method; + private String uri; + private Map params; + + public Request(String firstline) { + String[] splitFirstLine = firstline.split(" "); + method = splitFirstLine[0]; + uri = splitFirstLine[1]; + } + + public String getMethod() { + return method; + } + + public String getUri() { + return uri; + } + + public void setParams(Map params) { + this.params = params; + } + + public Map getParams() { + return params; + } +} diff --git a/src/main/java/webserver/Response.java b/src/main/java/webserver/response/Response.java similarity index 96% rename from src/main/java/webserver/Response.java rename to src/main/java/webserver/response/Response.java index 5c89a95..99d141c 100644 --- a/src/main/java/webserver/Response.java +++ b/src/main/java/webserver/response/Response.java @@ -1,4 +1,4 @@ -package webserver; +package webserver.response; import java.nio.charset.StandardCharsets; diff --git a/src/main/java/webserver/response/ResponseMaker.java b/src/main/java/webserver/response/ResponseMaker.java new file mode 100644 index 0000000..9567b3f --- /dev/null +++ b/src/main/java/webserver/response/ResponseMaker.java @@ -0,0 +1,33 @@ +package webserver.response; + +import webserver.logicexecutor.LogicExecutor; +import webserver.logicexecutor.LoginLogicExecutor; +import webserver.request.Request; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.HashMap; +import java.util.Map; + +public class ResponseMaker { + private final Map mapper = new HashMap<>(); + + public ResponseMaker() { + mapper.put("/user/create", new LoginLogicExecutor()); + } + + public Response getResponse(Request request) { + if (mapper.containsKey(request.getUri())) { + LogicExecutor logicExecutor = mapper.get(request.getUri()); + return logicExecutor.run(request); + } + try { + byte[] body = Files.readAllBytes(new File("./webapp" + request.getUri()).toPath()); + return new Response(StatusCode.OK, body); + } catch (IOException e) { + return new Response(StatusCode.OK, "헬로우 월드!".getBytes(StandardCharsets.UTF_8)); + } + } +} diff --git a/src/main/java/webserver/StatusCode.java b/src/main/java/webserver/response/StatusCode.java similarity index 89% rename from src/main/java/webserver/StatusCode.java rename to src/main/java/webserver/response/StatusCode.java index 7ab56ec..0b51202 100644 --- a/src/main/java/webserver/StatusCode.java +++ b/src/main/java/webserver/response/StatusCode.java @@ -1,4 +1,4 @@ -package webserver; +package webserver.response; public enum StatusCode { OK(200), diff --git a/webapp/user/form.html b/webapp/user/form.html index 96fe1bd..f7a3b56 100644 --- a/webapp/user/form.html +++ b/webapp/user/form.html @@ -75,7 +75,7 @@
-
+