diff --git a/build.gradle b/build.gradle index 8144c54..1e63a22 100644 --- a/build.gradle +++ b/build.gradle @@ -5,11 +5,18 @@ plugins { group 'org.example' version '1.0-SNAPSHOT' +configurations { + compileOnly { + extendsFrom annotationProcessor + } +} + repositories { mavenCentral() } dependencies { + implementation 'org.projectlombok:lombok:1.18.20' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1' testImplementation group: 'org.assertj', name: 'assertj-core', version: '3.22.0' @@ -22,6 +29,9 @@ dependencies { implementation group: 'org.apache.commons', name: 'commons-dbcp2', version: '2.9.0' // https://mvnrepository.com/artifact/com.h2database/h2 implementation group: 'com.h2database', name: 'h2', version: '2.1.210' + + compileOnly group: 'org.projectlombok', name: 'lombok', version: '1.18.22' + annotationProcessor group: 'org.projectlombok', name: 'lombok', version: '1.18.22' } test { diff --git a/docs/InputOutputStream.md b/docs/InputOutputStream.md new file mode 100644 index 0000000..b496e41 --- /dev/null +++ b/docs/InputOutputStream.md @@ -0,0 +1,2 @@ +# Input/Output Stream + diff --git a/src/main/java/model/User.java b/src/main/java/model/User.java index b7abb73..fec066c 100644 --- a/src/main/java/model/User.java +++ b/src/main/java/model/User.java @@ -1,34 +1,16 @@ package model; +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter public class User { private String userId; private String password; private String name; private String email; - public User(String userId, String password, String name, String email) { - this.userId = userId; - this.password = password; - this.name = name; - this.email = email; - } - - public String getUserId() { - return userId; - } - - public String getPassword() { - return password; - } - - public String getName() { - return name; - } - - public String getEmail() { - return email; - } - @Override public String toString() { return "User [userId=" + userId + ", password=" + password + ", name=" + name + ", email=" + email + "]"; diff --git a/src/main/java/webserver/Request.java b/src/main/java/webserver/Request.java new file mode 100644 index 0000000..9a7d47f --- /dev/null +++ b/src/main/java/webserver/Request.java @@ -0,0 +1,119 @@ +package webserver; + +import db.DataBase; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import model.User; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import util.HttpRequestUtils; +import util.IOUtils; +import webserver.domain.HttpMethod; +import webserver.domain.RequestHeader; +import webserver.domain.RequestLine; + +public class Request { + + private static final Logger log = LoggerFactory.getLogger(RequestHandler.class); + + private RequestHeader requestHeader; + private int contentLength; + + public RequestLine handleUserRequest(InputStream in) throws IOException { + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in)); + + makeRequestHeader(bufferedReader); + processHttpMethod(); + + return requestHeader.getRequestLine(); + } + + private void makeRequestHeader(BufferedReader bufferedReader) + throws IOException { + + String line = bufferedReader.readLine(); + String startLine = line; + log.debug("requestHeader: {}", line); + + List requestData = new ArrayList<>(); + while (!"".equals(line)) { + line = bufferedReader.readLine(); + log.debug("requestHeader: {}", line); + + if (line.contains("Content-Length")) { + String[] token = line.split(":"); + contentLength = Integer.parseInt(token[1].trim()); + } + + if (line == null) { + return; + } + requestData.add(line); + } + + requestHeader.setBody(IOUtils.readData(bufferedReader, contentLength)); + + + this.requestHeader = new RequestHeader(startLine, requestData); + } + + private void processHttpMethod() { + HttpMethod httpMethod = requestHeader.getRequestLine().getHttpMethod(); + String url = requestHeader.getRequestLine().getUrl(); + + if (httpMethod.equals(HttpMethod.GET)) { + int indexOfQueryParameter = url.indexOf('?'); + if (indexOfQueryParameter != -1) { + processQueryParameter(url, indexOfQueryParameter); + } + } else if (httpMethod.equals(HttpMethod.POST)) { + Map queryStrings = HttpRequestUtils.parseQueryString(requestHeader.getBody()); + saveUserInDatabase(queryStrings); + } + + } + + private void processQueryParameter(String url, int indexOfQueryParameter) { + String requestPath = url.substring(0, indexOfQueryParameter); + String queryString = url.substring(indexOfQueryParameter + 1); + + Map queryStringMap = HttpRequestUtils.parseQueryString(queryString); + + saveUserInDatabase(queryStringMap); + } + + private void saveUserInDatabase(Map queryStringMap) { + User user = new User(); + for (Entry entry : queryStringMap.entrySet()) { + switch (entry.getKey()) { + case "userId": + user.setUserId(entry.getValue()); + break; + case "name": + user.setName(entry.getValue()); + break; + case "password": + user.setPassword(entry.getValue()); + break; + case "email": + user.setEmail(URLDecoder.decode(entry.getValue(), StandardCharsets.UTF_8)); + break; + } + } + + DataBase.addUser(user); + DataBase.findAll().stream() + .forEach(userInDatabase -> log.debug("**Database.findAll() : {}", + userInDatabase.toString())); + //TODO : index.html로 redirection 되도록 처리해야하지 않을까? 요구사항에 없으니 패스 + } + +} \ No newline at end of file diff --git a/src/main/java/webserver/RequestHandler.java b/src/main/java/webserver/RequestHandler.java index 90195ec..ea6a257 100644 --- a/src/main/java/webserver/RequestHandler.java +++ b/src/main/java/webserver/RequestHandler.java @@ -1,6 +1,5 @@ package webserver; -import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -8,48 +7,32 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import webserver.domain.RequestLine; + 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 사용자 요청에 대한 처리는 이 곳에 구현하면 된다. - DataOutputStream dos = new DataOutputStream(out); - byte[] body = "Hello World".getBytes(); - 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 static final Logger log = LoggerFactory.getLogger(RequestHandler.class); + + private Socket connection; + private Request request = new Request(); + private Response response = new Response(); + + 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 사용자 요청에 대한 처리는 이 곳에 구현하면 된다. + RequestLine requestLine = request.handleUserRequest(in); + response.makeResponse(requestLine.getUrl(), out); + + } 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..e1709a5 --- /dev/null +++ b/src/main/java/webserver/Response.java @@ -0,0 +1,62 @@ +package webserver; + +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Response { + + private static final Logger log = LoggerFactory.getLogger(RequestHandler.class); + + public void makeResponse(String url, OutputStream out) { + DataOutputStream dos = new DataOutputStream(out); + + byte[] body = null; + + if (url.equals("/index.html") || url.equals("/user/form.html")) { + body = makeRequestBody(url); + } else { + body = "Hello World".getBytes(); + } + + response200Header(dos, body.length); + responseBody(dos, body); + } + + private byte[] makeRequestBody(String url) { + byte[] body = null; + + try { + body = Files.readAllBytes(new File("./webapp" + url).toPath()); + } catch (IOException e) { + e.printStackTrace(); + } + + return body; + } + + 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/domain/HttpMethod.java b/src/main/java/webserver/domain/HttpMethod.java new file mode 100644 index 0000000..7340cb2 --- /dev/null +++ b/src/main/java/webserver/domain/HttpMethod.java @@ -0,0 +1,5 @@ +package webserver.domain; + +public enum HttpMethod { + GET,POST; +} diff --git a/src/main/java/webserver/domain/RequestHeader.java b/src/main/java/webserver/domain/RequestHeader.java new file mode 100644 index 0000000..ee47ddb --- /dev/null +++ b/src/main/java/webserver/domain/RequestHeader.java @@ -0,0 +1,28 @@ +package webserver.domain; + +import java.util.ArrayList; +import java.util.List; +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +public class RequestHeader { + + private RequestLine requestLine; + private List requestHeaders; + private String body; + + private RequestHeader(){ + } + + public RequestHeader (String startLine, List requestData) { + this(); + this.requestLine = makeRequestLine(startLine); + } + + private RequestLine makeRequestLine(String startLine) { + String[] requestLine = startLine.split(" "); + return new RequestLine(requestLine[0], requestLine[1], requestLine[2]); + } +} diff --git a/src/main/java/webserver/domain/RequestLine.java b/src/main/java/webserver/domain/RequestLine.java new file mode 100644 index 0000000..58a2e6f --- /dev/null +++ b/src/main/java/webserver/domain/RequestLine.java @@ -0,0 +1,20 @@ +package webserver.domain; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class RequestLine { + + private HttpMethod httpMethod; + private String url; + private String httpVersion; + + public RequestLine(String httpMethod, String url, String httpVersion) { + this.httpMethod = HttpMethod.valueOf(httpMethod); + this.url = url; + this.httpVersion = httpVersion; + } + +} diff --git a/src/main/java/zjavastudy/InputStreamExample.java b/src/main/java/zjavastudy/InputStreamExample.java new file mode 100644 index 0000000..ed9ff69 --- /dev/null +++ b/src/main/java/zjavastudy/InputStreamExample.java @@ -0,0 +1,24 @@ +package zjavastudy; + +import java.io.IOException; +import java.io.InputStream; + +public class InputStreamExample { + + public static void main(String[] args) throws IOException { + InputStream inputStream = System.in; + +// int read = inputStream.read(); +// int read1 = inputStream.read(); +// System.out.println(read); +// System.out.println(read1); + + byte[] bytes = new byte[10]; + inputStream.read(bytes); + + for (byte aByte : bytes) { + char chr = (char) aByte; + System.out.println(chr); + } + } +} 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 @@
-
+