From e368189da0f01e9c28555ee7cec014017ffd85fb Mon Sep 17 00:00:00 2001 From: tmdgusya Date: Tue, 30 Mar 2021 14:32:40 +0900 Subject: [PATCH] =?UTF-8?q?[#3]=20feat:=20:cloud:=20ReturnValueHandler=20?= =?UTF-8?q?=EB=A5=BC=20=ED=86=B5=ED=95=B4=EC=84=9C=20view=20=EB=A5=BC=20Re?= =?UTF-8?q?solve=20=ED=95=98=EA=B1=B0=EB=82=98=20=EB=A6=AC=EB=8B=A4?= =?UTF-8?q?=EC=9D=B4=EB=A0=89=EC=85=98=EC=9D=84=20=ED=95=A0=20=EC=88=98=20?= =?UTF-8?q?=EC=9E=88=EB=8F=84=EB=A1=9D=20=ED=96=88=EC=8A=B5=EB=8B=88?= =?UTF-8?q?=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/controller/UserController.java | 67 ++++++++++ .../java/handler/mapping/PostMapping.java | 14 +++ .../returnValueHandle/ReturnValueHandler.java | 88 ++++++++++++++ src/main/java/util/ResponseData.java | 67 ++++++++++ src/main/java/webserver/RequestHandler.java | 114 ------------------ src/main/java/webserver/RequestMethod.java | 11 -- src/main/java/webserver/WebCat.java | 49 ++++++++ src/main/java/webserver/WebServer.java | 4 +- 8 files changed, 287 insertions(+), 127 deletions(-) create mode 100644 src/main/java/controller/UserController.java create mode 100644 src/main/java/handler/mapping/PostMapping.java create mode 100644 src/main/java/handler/returnValueHandle/ReturnValueHandler.java create mode 100644 src/main/java/util/ResponseData.java delete mode 100644 src/main/java/webserver/RequestHandler.java delete mode 100644 src/main/java/webserver/RequestMethod.java create mode 100644 src/main/java/webserver/WebCat.java diff --git a/src/main/java/controller/UserController.java b/src/main/java/controller/UserController.java new file mode 100644 index 0000000..73c20cd --- /dev/null +++ b/src/main/java/controller/UserController.java @@ -0,0 +1,67 @@ +package controller; + +import core.HttpRequest; +import core.HttpResponse; +import db.DataBase; +import handler.mapping.Controller; +import handler.mapping.GetMapping; +import handler.mapping.PostMapping; +import model.User; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import util.HttpRequestUtils; +import util.IOUtils; +import util.ResponseData; + +import java.io.DataOutputStream; +import java.util.Map; + +@Controller +public class UserController { + + private final static Logger log = LoggerFactory.getLogger(UserController.class); + + public UserController() { + } + + @GetMapping(url = "/") + public String root(HttpRequest httpRequest, HttpResponse httpResponse) { + return "index.html"; + } + + @PostMapping(url = "/users") + public String createUser(HttpRequest httpRequest, HttpResponse httpResponse) { + + final Map parameters = httpRequest.getRequestBody(); + + User user = new User(parameters.get("userId"), parameters.get("password"), parameters.get("name"), parameters.get("email")); + log.debug("User : {}" , user); + + DataBase.addUser(user); + + DataOutputStream dos = new DataOutputStream(httpResponse.getOut()); + return "redirect:/"; + } + + @GetMapping(url = "/users") + public String getUsers(HttpRequest httpRequest, HttpResponse httpResponse) { + log.info("12312312312"); + return "index.html"; + } + + @GetMapping(url = "/users/form") + public String createUserForm(HttpRequest httpRequest, HttpResponse httpResponse) { + return "user/form.html"; + } + + @GetMapping(url = "/users/login") + public String login(HttpRequest httpRequest, HttpResponse httpResponse) { + return "user/login.html"; + } + + @GetMapping(url = "/users/profile") + public String profile(HttpRequest httpRequest, HttpResponse httpResponse) { + return "user/profile.html"; + } + +} diff --git a/src/main/java/handler/mapping/PostMapping.java b/src/main/java/handler/mapping/PostMapping.java new file mode 100644 index 0000000..bfd50b6 --- /dev/null +++ b/src/main/java/handler/mapping/PostMapping.java @@ -0,0 +1,14 @@ +package handler.mapping; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface PostMapping { + + String url() default ""; + +} diff --git a/src/main/java/handler/returnValueHandle/ReturnValueHandler.java b/src/main/java/handler/returnValueHandle/ReturnValueHandler.java new file mode 100644 index 0000000..4e19b44 --- /dev/null +++ b/src/main/java/handler/returnValueHandle/ReturnValueHandler.java @@ -0,0 +1,88 @@ +package handler.returnValueHandle; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; + +public class ReturnValueHandler { + + private static final Logger log = LoggerFactory.getLogger(ReturnValueHandler.class); + + private final String returnValue; + private final DataOutputStream dos; + + private static final String PREFIX = "./webapp/"; + + public ReturnValueHandler(Object returnValue, DataOutputStream dos) { + this.returnValue = (String) returnValue; + this.dos = dos; + } + + public void handle() throws IOException { + if(returnValue.startsWith("redirect")) { + String url = returnValue.split(":")[1]; + response302Header(dos, url); + }else { + byte[] body = Files.readAllBytes(new File(PREFIX + returnValue).toPath()); + response200Header(dos, body.length); + responseBody(dos, body); + } + } + + private void response302HeaderWithCookies(DataOutputStream dos, String location, String cookie) { + try { + dos.writeBytes("HTTP/1.1 302 \r\n"); + dos.writeBytes(String.format("Location: %s \r\n", location)); + dos.writeBytes(String.format("Set-Cookie: %s \r\n", cookie)); + dos.writeBytes("\r\n"); + } catch (IOException e) { + log.error(e.getMessage()); + } + } + + private void response200HeaderWithCss(DataOutputStream dos, int length) { + try { + dos.writeBytes("HTTP/1.1 200 OK \r\n"); + dos.writeBytes("Content-Type: text/css;charset=utf-8 \r\n"); + dos.writeBytes(String.format("Content-Length: %d \r\n", length)); + dos.writeBytes("\r\n"); + } catch (IOException e) { + log.error(e.getMessage()); + } + } + + private void response302Header(DataOutputStream dos, String location) { + try { + dos.writeBytes("HTTP/1.1 302 \r\n"); + dos.writeBytes(String.format("Location: %s \r\n", location)); + dos.writeBytes("\r\n"); + } 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/util/ResponseData.java b/src/main/java/util/ResponseData.java new file mode 100644 index 0000000..ad369dc --- /dev/null +++ b/src/main/java/util/ResponseData.java @@ -0,0 +1,67 @@ +package util; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.DataOutputStream; +import java.io.IOException; + +public class ResponseData { + + private static final Logger log = LoggerFactory.getLogger(ResponseData.class); + + public static 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()); + } + } + + public static void response200HeaderWithCss(DataOutputStream dos, int lengthOfBodyContent) { + try { + dos.writeBytes("HTTP/1.1 200 OK \r\n"); + dos.writeBytes("Content-Type: text/css;charset=utf-8\r\n"); + dos.writeBytes("Content-Length: " + lengthOfBodyContent + "\r\n"); + dos.writeBytes("\r\n"); + } catch (IOException e) { + log.error(e.getMessage()); + } + } + + public static void response302Header(DataOutputStream dos, String location) { + log.debug("location : {}", location); + try { + dos.writeBytes("HTTP/1.1 302 Found \r\n"); // 원래는 200 + dos.writeBytes("Location: " + location+"\r\n"); + dos.writeBytes("\r\n"); + } catch (IOException e) { + log.error(e.getMessage()); + } + } + + public static void response302HeaderWithCookie(DataOutputStream dos, String location, String cookie) { + log.debug("location : {}", location); + try { + dos.writeBytes("HTTP/1.1 302 Found \r\n"); // 원래는 200 + dos.writeBytes("Location: " + location+"\r\n"); + dos.writeBytes("Set-Cookie: " + cookie + "\r\n"); + dos.writeBytes("\r\n"); + } catch (IOException e) { + log.error(e.getMessage()); + } + } + + public static 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/RequestHandler.java b/src/main/java/webserver/RequestHandler.java deleted file mode 100644 index fda429c..0000000 --- a/src/main/java/webserver/RequestHandler.java +++ /dev/null @@ -1,114 +0,0 @@ -package webserver; - -import java.io.*; -import java.net.Socket; -import java.nio.file.Files; -import java.util.HashMap; -import java.util.Map; - -import model.User; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import util.IOUtils; - -public class RequestHandler extends Thread { - private static final Logger log = LoggerFactory.getLogger(RequestHandler.class); - - private Socket connection; - - public RequestHandler(Socket connectionSocket) { - this.connection = connectionSocket; - } - - - 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 사용자 요청에 대한 처리는 이 곳에 구현하면 된다. - - BufferedReader br = new BufferedReader(new InputStreamReader(in)); - String line = br.readLine(); - log.debug("line : {}", line); - final Map headers = parseHeaders(br); - log.debug("headers : {}, {}", headers.get("Content-Length"), headers.get("Content-Type")); - String[] firstLine = line.split(" "); - RequestMethod method = RequestMethod.of(firstLine[0]); - String url = firstLine[1]; - log.info("url : {}", url); - - - - - if(url.startsWith("/user/create")) { - if(method == RequestMethod.POST) { - String body = IOUtils.readData(br, Integer.parseInt(headers.get("Content-Length"))); - log.debug("body : {}", body); - final Map stringQuery = parseQueryString(body); - User user = new User(stringQuery.get("userId"), stringQuery.get("password"), stringQuery.get("name"), stringQuery.get("email")); - log.debug("user : {}", user); - } - - } - - DataOutputStream dos = new DataOutputStream(out); - - byte[] body = Files.readAllBytes(new File("./webapp/"+url).toPath()); - response200Header(dos, body.length); - responseBody(dos, body); - } 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()); - } - } - - private Map parseHeaders(BufferedReader br) throws IOException { - Map headers = new HashMap<>(); - String line = br.readLine(); - while (!"".equals(line)) { - String[] header = line.split(": "); - headers.put(header[0], header[1]); - line = br.readLine(); - } - return headers; - } - - private Map parseUrl(String url) { - int i = url.indexOf('?'); - if(i == -1) { - return new HashMap<>(); - } - return parseQueryString(url.substring(i + 1, url.length())); - } - - private Map parseQueryString(String queryString) { - Map queryStrings = new HashMap<>(); - String[] split = queryString.split("&"); - for(String query : split) { - String[] ss = query.split("="); - queryStrings.put(ss[0], ss[1]); - } - return queryStrings; - } - -} diff --git a/src/main/java/webserver/RequestMethod.java b/src/main/java/webserver/RequestMethod.java deleted file mode 100644 index c03544e..0000000 --- a/src/main/java/webserver/RequestMethod.java +++ /dev/null @@ -1,11 +0,0 @@ -package webserver; - -import java.util.Locale; - -public enum RequestMethod { - GET, POST; - - public static RequestMethod of(String method) { - return RequestMethod.valueOf(method.toUpperCase()); - } -} diff --git a/src/main/java/webserver/WebCat.java b/src/main/java/webserver/WebCat.java new file mode 100644 index 0000000..97073d8 --- /dev/null +++ b/src/main/java/webserver/WebCat.java @@ -0,0 +1,49 @@ +package webserver; + +import java.io.*; +import java.lang.reflect.InvocationTargetException; +import java.net.Socket; + +import core.HttpRequest; +import core.HttpResponse; +import handler.mapping.MappingUrlHandler; +import handler.returnValueHandle.ReturnValueHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class WebCat extends Thread { + + private static final Logger log = LoggerFactory.getLogger(WebCat.class); + + private Socket connection; + + public WebCat(Socket connectionSocket) { + this.connection = connectionSocket; + } + + public void run() { + log.debug("New Client Connect! Connected IP : {}, Port : {}", connection.getInetAddress(), connection.getPort()); + + try (InputStream in = connection.getInputStream(); OutputStream out = connection.getOutputStream()) { + HttpRequest httpRequest = new HttpRequest(in); + httpRequest.run(); + HttpResponse httpResponse = new HttpResponse(out); + MappingUrlHandler mappingUrlHandler = new MappingUrlHandler(httpRequest.getMethod(), httpRequest.getUrl()); + DataOutputStream dos = new DataOutputStream(out); + try { + Object returnValue = mappingUrlHandler.invokeMethod(httpRequest, httpResponse); + //TODO 여기서 returnValue 를 resolve 하는 방식을 찾아야 한다. + ReturnValueHandler returnValueHandler = new ReturnValueHandler(returnValue, dos); + returnValueHandler.handle(); + } catch (IllegalAccessException | InvocationTargetException | ClassNotFoundException | NoSuchMethodException | InstantiationException e) { + e.printStackTrace(); + } + log.info(httpRequest.toString()); + log.info(httpResponse.toString()); + } catch (IOException e) { + e.printStackTrace(); + } + + } + +} diff --git a/src/main/java/webserver/WebServer.java b/src/main/java/webserver/WebServer.java index 91f4a0f..6bec283 100644 --- a/src/main/java/webserver/WebServer.java +++ b/src/main/java/webserver/WebServer.java @@ -26,8 +26,8 @@ public static void main(String args[]) throws Exception { // 클라이언트가 연결될때까지 대기한다. Socket connection; while ((connection = listenSocket.accept()) != null) { - RequestHandler requestHandler = new RequestHandler(connection); - requestHandler.start(); + WebCat webCat = new WebCat(connection); + webCat.start(); } } }