From 753b3e1a153f19b8588d9a6cc1b1ce4629c3537c Mon Sep 17 00:00:00 2001 From: odo27 Date: Sat, 9 Sep 2023 14:57:25 +0900 Subject: [PATCH 01/10] =?UTF-8?q?feat:=20Controller=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coyote/http11/AbstractController.java | 27 ++++ .../org/apache/coyote/http11/Controller.java | 6 + .../coyote/http11/ExceptionHandler.java | 4 +- .../apache/coyote/http11/HomeController.java | 15 ++ .../apache/coyote/http11/Http11Processor.java | 133 ++---------------- .../org/apache/coyote/http11/HttpRequest.java | 10 +- .../apache/coyote/http11/LoginController.java | 77 ++++++++++ .../coyote/http11/RegisterController.java | 49 +++++++ .../apache/coyote/http11/RequestMapping.java | 35 +++++ .../coyote/http11/ResourceController.java | 31 ++++ .../apache/coyote/http11/ResourceLoader.java | 10 +- 11 files changed, 270 insertions(+), 127 deletions(-) create mode 100644 tomcat/src/main/java/org/apache/coyote/http11/AbstractController.java create mode 100644 tomcat/src/main/java/org/apache/coyote/http11/Controller.java create mode 100644 tomcat/src/main/java/org/apache/coyote/http11/HomeController.java create mode 100644 tomcat/src/main/java/org/apache/coyote/http11/LoginController.java create mode 100644 tomcat/src/main/java/org/apache/coyote/http11/RegisterController.java create mode 100644 tomcat/src/main/java/org/apache/coyote/http11/RequestMapping.java create mode 100644 tomcat/src/main/java/org/apache/coyote/http11/ResourceController.java diff --git a/tomcat/src/main/java/org/apache/coyote/http11/AbstractController.java b/tomcat/src/main/java/org/apache/coyote/http11/AbstractController.java new file mode 100644 index 0000000000..4dab0acac9 --- /dev/null +++ b/tomcat/src/main/java/org/apache/coyote/http11/AbstractController.java @@ -0,0 +1,27 @@ +package org.apache.coyote.http11; + +import static org.apache.coyote.http11.HttpMethod.GET; +import static org.apache.coyote.http11.HttpMethod.POST; +import static org.apache.coyote.http11.HttpStatus.BAD_REQUEST; + +public abstract class AbstractController implements Controller { + + @Override + public HttpResponse service(HttpRequest request) { + if (request.method() == POST) { + return doPost(request); + } + if (request.method() == GET) { + return doGet(request); + } + throw new HttpException(BAD_REQUEST, "지원되지 않는 요청입니다"); + } + + protected HttpResponse doPost(HttpRequest request) { + throw new HttpException(BAD_REQUEST, "지원되지 않는 요청입니다"); + } + + protected HttpResponse doGet(HttpRequest request) { + throw new HttpException(BAD_REQUEST, "지원되지 않는 요청입니다"); + } +} diff --git a/tomcat/src/main/java/org/apache/coyote/http11/Controller.java b/tomcat/src/main/java/org/apache/coyote/http11/Controller.java new file mode 100644 index 0000000000..c783407f30 --- /dev/null +++ b/tomcat/src/main/java/org/apache/coyote/http11/Controller.java @@ -0,0 +1,6 @@ +package org.apache.coyote.http11; + +public interface Controller { + + HttpResponse service(HttpRequest request); +} diff --git a/tomcat/src/main/java/org/apache/coyote/http11/ExceptionHandler.java b/tomcat/src/main/java/org/apache/coyote/http11/ExceptionHandler.java index e64149acbc..fc7d2b0f46 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/ExceptionHandler.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/ExceptionHandler.java @@ -2,13 +2,11 @@ import static org.apache.coyote.http11.ContentType.TEXT_HTML; -import java.io.IOException; - public class ExceptionHandler { private static final String RESOURCE_PATH_FORMAT = "static/%s.html"; - public HttpResponse handleException(HttpException e) throws IOException { + public HttpResponse handleException(HttpException e) { HttpStatus httpStatus = e.httpStatus(); int code = httpStatus.statusCode(); ResourceLoader resourceLoader = new ResourceLoader(); diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HomeController.java b/tomcat/src/main/java/org/apache/coyote/http11/HomeController.java new file mode 100644 index 0000000000..41025b6990 --- /dev/null +++ b/tomcat/src/main/java/org/apache/coyote/http11/HomeController.java @@ -0,0 +1,15 @@ +package org.apache.coyote.http11; + +import static org.apache.coyote.http11.ContentType.TEXT_HTML; +import static org.apache.coyote.http11.HttpStatus.OK; + +public class HomeController extends AbstractController { + + @Override + protected HttpResponse doGet(HttpRequest request) { + return HttpResponse.status(OK) + .body("Hello world!") + .contentType(TEXT_HTML) + .build(); + } +} diff --git a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java index 5f3308bc2e..c8dfb68363 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java @@ -1,26 +1,12 @@ package org.apache.coyote.http11; -import static org.apache.coyote.http11.ContentType.TEXT_CSS; -import static org.apache.coyote.http11.ContentType.TEXT_HTML; -import static org.apache.coyote.http11.HttpMethod.GET; -import static org.apache.coyote.http11.HttpMethod.POST; -import static org.apache.coyote.http11.HttpStatus.BAD_REQUEST; -import static org.apache.coyote.http11.HttpStatus.FOUND; -import static org.apache.coyote.http11.HttpStatus.OK; -import static org.apache.coyote.http11.HttpStatus.UNAUTHORIZED; - import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.Socket; -import java.util.Optional; -import java.util.UUID; -import nextstep.jwp.db.InMemoryUserRepository; import nextstep.jwp.exception.UncheckedServletException; -import nextstep.jwp.model.User; -import org.apache.catalina.Session; import org.apache.catalina.SessionManager; import org.apache.coyote.Processor; import org.slf4j.Logger; @@ -28,16 +14,21 @@ public class Http11Processor implements Runnable, Processor { - private static final String INDEX_HTML = "/index.html"; - private static final String JSESSIONID = "JSESSIONID"; private static final Logger log = LoggerFactory.getLogger(Http11Processor.class); private final Socket connection; - private final SessionManager sessionManager; + private final RequestMapping requestMapping; public Http11Processor(Socket connection) { this.connection = connection; - this.sessionManager = new SessionManager(); + SessionManager sessionManager = new SessionManager(); + ResourceLoader resourceLoader = new ResourceLoader(); + requestMapping = new RequestMapping( + new HomeController(), + new LoginController(resourceLoader, sessionManager), + new RegisterController(resourceLoader), + new ResourceController(resourceLoader) + ); } @Override @@ -60,114 +51,14 @@ public void process(final Socket connection) { } } - private HttpResponse process(BufferedReader bufferedReader) throws IOException { + private HttpResponse process(BufferedReader bufferedReader) { ExceptionHandler exceptionHandler = new ExceptionHandler(); try { HttpRequest httpRequest = HttpRequest.from(bufferedReader); - return handleRequest(httpRequest); + Controller controller = requestMapping.getController(httpRequest); + return controller.service(httpRequest); } catch (HttpException e) { return exceptionHandler.handleException(e); } } - - private HttpResponse handleRequest(HttpRequest httpRequest) throws IOException { - ResourceLoader resourceLoader = new ResourceLoader(); - - if (httpRequest.method() == POST) { - if (httpRequest.uri().equals("/register")) { - return register(httpRequest); - } - if (httpRequest.uri().equals("/login")) { - Optional jsessionid = httpRequest.getCookie(JSESSIONID); - if (jsessionid.isPresent()) { - return loginWithSession(jsessionid.get()); - } - return login(httpRequest); - } - throw new HttpException(BAD_REQUEST, "지원되지 않는 uri 입니다"); - } - if (httpRequest.method() == GET) { - if (httpRequest.uri().equals("/")) { - return HttpResponse.status(OK) - .body("Hello world!") - .contentType(TEXT_HTML) - .build(); - } - if (httpRequest.uri().equals("/login")) { - Optional jsessionid = httpRequest.getCookie(JSESSIONID); - if (jsessionid.isPresent()) { - return loginWithSession(jsessionid.get()); - } - return HttpResponse.status(OK) - .body(resourceLoader.load("static/login.html")) - .contentType(TEXT_HTML) - .build(); - } - if (httpRequest.uri().equals("/register")) { - return HttpResponse.status(OK) - .body(resourceLoader.load("static/register.html")) - .contentType(TEXT_HTML) - .build(); - } - Optional acceptHeader = httpRequest.getHeader("Accept"); - if (acceptHeader.isPresent() && acceptHeader.get().contains("text/css")) { - return HttpResponse.status(OK) - .body(resourceLoader.load("static" + httpRequest.uri())) - .contentType(TEXT_CSS) - .build(); - } - return HttpResponse.status(OK) - .body(resourceLoader.load("static" + httpRequest.uri())) - .contentType(TEXT_HTML) - .build(); - } - throw new HttpException(BAD_REQUEST, "지원되지 않는 요청입니다"); - } - - private HttpResponse register(HttpRequest httpRequest) { - FormData formData = FormData.from(httpRequest.getBody()); - String account = formData.get("account"); - String password = formData.get("password"); - String email = formData.get("email"); - if (InMemoryUserRepository.findByAccount(account).isPresent()) { - throw new HttpException(BAD_REQUEST, "이미 존재하는 아이디입니다. 다른 아이디로 가입해주세요"); - } - User user = new User(account, password, email); - InMemoryUserRepository.save(user); - - return HttpResponse.status(FOUND) - .redirectUri(INDEX_HTML) - .build(); - } - - private HttpResponse loginWithSession(String jsessionid) { - Session session = sessionManager.findSession(jsessionid) - .orElseThrow(() -> new HttpException(UNAUTHORIZED, "잘못된 세션 아이디입니다")); - if (session.getAttribute("user").isEmpty()) { - throw new HttpException(UNAUTHORIZED, "세션에 회원정보가 존재하지 않습니다"); - } - return HttpResponse.status(FOUND) - .redirectUri(INDEX_HTML) - .build(); - } - - private HttpResponse login(HttpRequest httpRequest) { - FormData formData = FormData.from(httpRequest.getBody()); - String account = formData.get("account"); - String password = formData.get("password"); - Optional user = InMemoryUserRepository.findByAccount(account); - if (user.isPresent() && user.get().checkPassword(password)) { - String jsessionid = UUID.randomUUID().toString(); - String userInfo = user.get().toString(); - log.info(userInfo); - Session session = new Session(jsessionid); - session.setAttribute("user", user.get()); - sessionManager.add(session); - return HttpResponse.status(FOUND) - .redirectUri(INDEX_HTML) - .cookie(JSESSIONID, jsessionid) - .build(); - } - throw new HttpException(UNAUTHORIZED, "아이디나 비밀번호를 확인해주세요"); - } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequest.java b/tomcat/src/main/java/org/apache/coyote/http11/HttpRequest.java index fb6b7e7868..61a5873566 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/HttpRequest.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/HttpRequest.java @@ -31,7 +31,15 @@ private HttpRequest(HttpMethod httpMethod, String uri, Map heade this.body = body; } - public static HttpRequest from(BufferedReader bufferedReader) throws IOException { + public static HttpRequest from(BufferedReader bufferedReader) { + try { + return read(bufferedReader); + } catch (IOException e) { + throw new HttpException(BAD_REQUEST, "요청을 읽을 수 없습니다"); + } + } + + public static HttpRequest read(BufferedReader bufferedReader) throws IOException { String firstLine = bufferedReader.readLine(); String[] splitByBlank = firstLine.split(BLANK); String method = splitByBlank[0]; diff --git a/tomcat/src/main/java/org/apache/coyote/http11/LoginController.java b/tomcat/src/main/java/org/apache/coyote/http11/LoginController.java new file mode 100644 index 0000000000..53f81159db --- /dev/null +++ b/tomcat/src/main/java/org/apache/coyote/http11/LoginController.java @@ -0,0 +1,77 @@ +package org.apache.coyote.http11; + +import static org.apache.coyote.http11.ContentType.TEXT_HTML; +import static org.apache.coyote.http11.HttpStatus.FOUND; +import static org.apache.coyote.http11.HttpStatus.OK; +import static org.apache.coyote.http11.HttpStatus.UNAUTHORIZED; + +import java.util.Optional; +import java.util.UUID; +import nextstep.jwp.db.InMemoryUserRepository; +import nextstep.jwp.model.User; +import org.apache.catalina.Session; +import org.apache.catalina.SessionManager; + +public class LoginController extends AbstractController { + + private static final String JSESSIONID = "JSESSIONID"; + private static final String INDEX_HTML = "/index.html"; + + private final ResourceLoader resourceLoader; + private final SessionManager sessionManager; + + public LoginController(ResourceLoader resourceLoader, SessionManager sessionManager) { + this.resourceLoader = resourceLoader; + this.sessionManager = sessionManager; + } + + @Override + protected HttpResponse doPost(HttpRequest request) { + Optional jsessionid = request.getCookie(JSESSIONID); + if (jsessionid.isPresent()) { + return loginWithSession(jsessionid.get()); + } + return login(request); + } + + @Override + protected HttpResponse doGet(HttpRequest request) { + Optional jsessionid = request.getCookie(JSESSIONID); + if (jsessionid.isPresent()) { + return loginWithSession(jsessionid.get()); + } + return HttpResponse.status(OK) + .body(resourceLoader.load("static/login.html")) + .contentType(TEXT_HTML) + .build(); + } + + private HttpResponse loginWithSession(String jsessionid) { + Session session = sessionManager.findSession(jsessionid) + .orElseThrow(() -> new HttpException(UNAUTHORIZED, "잘못된 세션 아이디입니다")); + if (session.getAttribute("user").isEmpty()) { + throw new HttpException(UNAUTHORIZED, "세션에 회원정보가 존재하지 않습니다"); + } + return HttpResponse.status(FOUND) + .redirectUri(INDEX_HTML) + .build(); + } + + private HttpResponse login(HttpRequest httpRequest) { + FormData formData = FormData.from(httpRequest.getBody()); + String account = formData.get("account"); + String password = formData.get("password"); + Optional user = InMemoryUserRepository.findByAccount(account); + if (user.isPresent() && user.get().checkPassword(password)) { + String jsessionid = UUID.randomUUID().toString(); + Session session = new Session(jsessionid); + session.setAttribute("user", user.get()); + sessionManager.add(session); + return HttpResponse.status(FOUND) + .redirectUri(INDEX_HTML) + .cookie(JSESSIONID, jsessionid) + .build(); + } + throw new HttpException(UNAUTHORIZED, "아이디나 비밀번호를 확인해주세요"); + } +} diff --git a/tomcat/src/main/java/org/apache/coyote/http11/RegisterController.java b/tomcat/src/main/java/org/apache/coyote/http11/RegisterController.java new file mode 100644 index 0000000000..6a1e24672c --- /dev/null +++ b/tomcat/src/main/java/org/apache/coyote/http11/RegisterController.java @@ -0,0 +1,49 @@ +package org.apache.coyote.http11; + +import static org.apache.coyote.http11.ContentType.TEXT_HTML; +import static org.apache.coyote.http11.HttpStatus.BAD_REQUEST; +import static org.apache.coyote.http11.HttpStatus.FOUND; +import static org.apache.coyote.http11.HttpStatus.OK; + +import nextstep.jwp.db.InMemoryUserRepository; +import nextstep.jwp.model.User; + +public class RegisterController extends AbstractController { + + private static final String INDEX_HTML = "/index.html"; + + private final ResourceLoader resourceLoader; + + public RegisterController(ResourceLoader resourceLoader) { + this.resourceLoader = resourceLoader; + } + + @Override + protected HttpResponse doPost(HttpRequest request) { + return register(request); + } + + @Override + protected HttpResponse doGet(HttpRequest request) { + return HttpResponse.status(OK) + .body(resourceLoader.load("static/register.html")) + .contentType(TEXT_HTML) + .build(); + } + + private HttpResponse register(HttpRequest request) { + FormData formData = FormData.from(request.getBody()); + String account = formData.get("account"); + String password = formData.get("password"); + String email = formData.get("email"); + if (InMemoryUserRepository.findByAccount(account).isPresent()) { + throw new HttpException(BAD_REQUEST, "이미 존재하는 아이디입니다. 다른 아이디로 가입해주세요"); + } + User user = new User(account, password, email); + InMemoryUserRepository.save(user); + + return HttpResponse.status(FOUND) + .redirectUri(INDEX_HTML) + .build(); + } +} diff --git a/tomcat/src/main/java/org/apache/coyote/http11/RequestMapping.java b/tomcat/src/main/java/org/apache/coyote/http11/RequestMapping.java new file mode 100644 index 0000000000..9d14883496 --- /dev/null +++ b/tomcat/src/main/java/org/apache/coyote/http11/RequestMapping.java @@ -0,0 +1,35 @@ +package org.apache.coyote.http11; + +public class RequestMapping { + + private final HomeController homeController; + private final LoginController loginController; + private final RegisterController registerController; + private final ResourceController resourceController; + + public RequestMapping( + HomeController homeController, + LoginController loginController, + RegisterController registerController, + ResourceController resourceController + ) { + this.homeController = homeController; + this.loginController = loginController; + this.registerController = registerController; + this.resourceController = resourceController; + } + + public Controller getController(HttpRequest request) { + String uri = request.uri(); + if (uri.equals("/")) { + return homeController; + } + if (uri.equals("/login")) { + return loginController; + } + if (uri.equals("/register")) { + return registerController; + } + return resourceController; + } +} diff --git a/tomcat/src/main/java/org/apache/coyote/http11/ResourceController.java b/tomcat/src/main/java/org/apache/coyote/http11/ResourceController.java new file mode 100644 index 0000000000..d6f5b07408 --- /dev/null +++ b/tomcat/src/main/java/org/apache/coyote/http11/ResourceController.java @@ -0,0 +1,31 @@ +package org.apache.coyote.http11; + +import static org.apache.coyote.http11.ContentType.TEXT_CSS; +import static org.apache.coyote.http11.ContentType.TEXT_HTML; +import static org.apache.coyote.http11.HttpStatus.OK; + +import java.util.Optional; + +public class ResourceController extends AbstractController { + + private final ResourceLoader resourceLoader; + + public ResourceController(ResourceLoader resourceLoader) { + this.resourceLoader = resourceLoader; + } + + @Override + protected HttpResponse doGet(HttpRequest request) { + Optional acceptHeader = request.getHeader("Accept"); + if (acceptHeader.isPresent() && acceptHeader.get().contains("text/css")) { + return HttpResponse.status(OK) + .body(resourceLoader.load("static" + request.uri())) + .contentType(TEXT_CSS) + .build(); + } + return HttpResponse.status(OK) + .body(resourceLoader.load("static" + request.uri())) + .contentType(TEXT_HTML) + .build(); + } +} diff --git a/tomcat/src/main/java/org/apache/coyote/http11/ResourceLoader.java b/tomcat/src/main/java/org/apache/coyote/http11/ResourceLoader.java index d6d4f01404..81538c3d98 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/ResourceLoader.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/ResourceLoader.java @@ -9,11 +9,17 @@ public class ResourceLoader { - public String load(String path) throws IOException { + public String load(String path) { URL resource = getClass().getClassLoader().getResource(path); if (resource == null) { throw new HttpException(BAD_REQUEST, "요청받은 리소스가 존재하지 않습니다"); } - return new String(Files.readAllBytes(new File(resource.getFile()).toPath())); + File file = new File(resource.getFile()); + try { + byte[] bytes = Files.readAllBytes(file.toPath()); + return new String(bytes); + } catch (IOException e) { + throw new HttpException(BAD_REQUEST, "요청받은 리소스가 존재하지 않습니다"); + } } } From a09fa1798c8dbfddf68c107bc076c287c17b4721 Mon Sep 17 00:00:00 2001 From: odo27 Date: Sun, 10 Sep 2023 13:52:50 +0900 Subject: [PATCH 02/10] =?UTF-8?q?feat:=20=EC=8A=A4=EB=A0=88=EB=93=9C=20?= =?UTF-8?q?=ED=95=99=EC=8A=B5=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- study/src/main/resources/application.yml | 2 +- .../thread/stage0/SynchronizationTest.java | 25 +++++++---------- .../java/thread/stage0/ThreadPoolsTest.java | 28 ++++++++----------- 3 files changed, 23 insertions(+), 32 deletions(-) diff --git a/study/src/main/resources/application.yml b/study/src/main/resources/application.yml index 4e8655a962..a2127eeacb 100644 --- a/study/src/main/resources/application.yml +++ b/study/src/main/resources/application.yml @@ -4,6 +4,6 @@ handlebars: server: tomcat: accept-count: 1 - max-connections: 1 + max-connections: 10 threads: max: 2 diff --git a/study/src/test/java/thread/stage0/SynchronizationTest.java b/study/src/test/java/thread/stage0/SynchronizationTest.java index 0333c18e3b..6297f3dfdf 100644 --- a/study/src/test/java/thread/stage0/SynchronizationTest.java +++ b/study/src/test/java/thread/stage0/SynchronizationTest.java @@ -1,29 +1,24 @@ package thread.stage0; -import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.stream.IntStream; - -import static org.assertj.core.api.Assertions.assertThat; +import org.junit.jupiter.api.Test; /** - * 다중 스레드 환경에서 두 개 이상의 스레드가 변경 가능한(mutable) 공유 데이터를 동시에 업데이트하면 경쟁 조건(race condition)이 발생한다. - * 자바는 공유 데이터에 대한 스레드 접근을 동기화(synchronization)하여 경쟁 조건을 방지한다. - * 동기화된 블록은 하나의 스레드만 접근하여 실행할 수 있다. - * - * Synchronization - * https://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html + * 다중 스레드 환경에서 두 개 이상의 스레드가 변경 가능한(mutable) 공유 데이터를 동시에 업데이트하면 경쟁 조건(race condition)이 발생한다. 자바는 공유 데이터에 대한 스레드 접근을 + * 동기화(synchronization)하여 경쟁 조건을 방지한다. 동기화된 블록은 하나의 스레드만 접근하여 실행할 수 있다. + *

+ * Synchronization https://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html */ class SynchronizationTest { /** - * 테스트가 성공하도록 SynchronizedMethods 클래스에 동기화를 적용해보자. - * synchronized 키워드에 대하여 찾아보고 적용하면 된다. - * - * Guide to the Synchronized Keyword in Java - * https://www.baeldung.com/java-synchronized + * 테스트가 성공하도록 SynchronizedMethods 클래스에 동기화를 적용해보자. synchronized 키워드에 대하여 찾아보고 적용하면 된다. + *

+ * Guide to the Synchronized Keyword in Java https://www.baeldung.com/java-synchronized */ @Test void testSynchronized() throws InterruptedException { @@ -41,7 +36,7 @@ private static final class SynchronizedMethods { private int sum = 0; - public void calculate() { + public synchronized void calculate() { setSum(getSum() + 1); } diff --git a/study/src/test/java/thread/stage0/ThreadPoolsTest.java b/study/src/test/java/thread/stage0/ThreadPoolsTest.java index 238611ebfe..afe5ff6db2 100644 --- a/study/src/test/java/thread/stage0/ThreadPoolsTest.java +++ b/study/src/test/java/thread/stage0/ThreadPoolsTest.java @@ -1,23 +1,19 @@ package thread.stage0; -import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import static org.assertj.core.api.Assertions.assertThat; import java.util.concurrent.Executors; import java.util.concurrent.ThreadPoolExecutor; - -import static org.assertj.core.api.Assertions.assertThat; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * 스레드 풀은 무엇이고 어떻게 동작할까? - * 테스트를 통과시키고 왜 해당 결과가 나왔는지 생각해보자. - * - * Thread Pools - * https://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html - * - * Introduction to Thread Pools in Java - * https://www.baeldung.com/thread-pool-java-and-guava + * 스레드 풀은 무엇이고 어떻게 동작할까? 테스트를 통과시키고 왜 해당 결과가 나왔는지 생각해보자. + *

+ * Thread Pools https://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html + *

+ * Introduction to Thread Pools in Java https://www.baeldung.com/thread-pool-java-and-guava */ class ThreadPoolsTest { @@ -31,8 +27,8 @@ void testNewFixedThreadPool() { executor.submit(logWithSleep("hello fixed thread pools")); // 올바른 값으로 바꿔서 테스트를 통과시키자. - final int expectedPoolSize = 0; - final int expectedQueueSize = 0; + final int expectedPoolSize = 2; + final int expectedQueueSize = 1; assertThat(expectedPoolSize).isEqualTo(executor.getPoolSize()); assertThat(expectedQueueSize).isEqualTo(executor.getQueue().size()); @@ -46,7 +42,7 @@ void testNewCachedThreadPool() { executor.submit(logWithSleep("hello cached thread pools")); // 올바른 값으로 바꿔서 테스트를 통과시키자. - final int expectedPoolSize = 0; + final int expectedPoolSize = 3; final int expectedQueueSize = 0; assertThat(expectedPoolSize).isEqualTo(executor.getPoolSize()); From 28366bb8587e4c376deb56b930404b7a1ecd60d7 Mon Sep 17 00:00:00 2001 From: odo27 Date: Sun, 10 Sep 2023 20:37:19 +0900 Subject: [PATCH 03/10] =?UTF-8?q?refactor:=20=ED=8C=A8=ED=82=A4=EC=A7=80?= =?UTF-8?q?=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jwp/common}/FormData.java | 7 +- .../jwp/common}/ResourceLoader.java | 9 ++- .../nextstep/jwp/config/ControllerConfig.java | 37 +++++++++ .../nextstep/jwp/exception/AuthException.java | 15 ++++ .../jwp/exception/AuthExceptionType.java | 34 ++++++++ .../nextstep/jwp/exception/BaseException.java | 9 +++ .../jwp/exception/BaseExceptionType.java | 10 +++ .../jwp/exception/ControllerException.java | 15 ++++ .../exception/ControllerExceptionType.java | 30 ++++++++ .../jwp/exception/ResourceException.java | 15 ++++ .../jwp/exception/ResourceExceptionType.java | 29 +++++++ .../jwp/presentation}/AbstractController.java | 14 ++-- .../nextstep/jwp/presentation/Controller.java | 9 +++ .../ExceptionControllerAdvice.java | 24 ++++++ .../jwp/presentation/FrontController.java | 25 ++++++ .../jwp/presentation}/HomeController.java | 5 +- .../jwp/presentation/LoginController.java | 44 +++++++++++ .../jwp/presentation}/RegisterController.java | 13 +++- .../jwp/presentation}/RequestMapping.java | 4 +- .../jwp/presentation}/ResourceController.java | 5 +- .../nextstep/jwp/service/LoginService.java | 58 ++++++++++++++ .../org/apache/coyote/http11/Controller.java | 6 -- .../apache/coyote/http11/Http11Processor.java | 21 ++--- ...Handler.java => HttpExceptionHandler.java} | 4 +- .../apache/coyote/http11/LoginController.java | 77 ------------------- 25 files changed, 402 insertions(+), 117 deletions(-) rename tomcat/src/main/java/{org/apache/coyote/http11 => nextstep/jwp/common}/FormData.java (82%) rename tomcat/src/main/java/{org/apache/coyote/http11 => nextstep/jwp/common}/ResourceLoader.java (61%) create mode 100644 tomcat/src/main/java/nextstep/jwp/config/ControllerConfig.java create mode 100644 tomcat/src/main/java/nextstep/jwp/exception/AuthException.java create mode 100644 tomcat/src/main/java/nextstep/jwp/exception/AuthExceptionType.java create mode 100644 tomcat/src/main/java/nextstep/jwp/exception/BaseException.java create mode 100644 tomcat/src/main/java/nextstep/jwp/exception/BaseExceptionType.java create mode 100644 tomcat/src/main/java/nextstep/jwp/exception/ControllerException.java create mode 100644 tomcat/src/main/java/nextstep/jwp/exception/ControllerExceptionType.java create mode 100644 tomcat/src/main/java/nextstep/jwp/exception/ResourceException.java create mode 100644 tomcat/src/main/java/nextstep/jwp/exception/ResourceExceptionType.java rename tomcat/src/main/java/{org/apache/coyote/http11 => nextstep/jwp/presentation}/AbstractController.java (55%) create mode 100644 tomcat/src/main/java/nextstep/jwp/presentation/Controller.java create mode 100644 tomcat/src/main/java/nextstep/jwp/presentation/ExceptionControllerAdvice.java create mode 100644 tomcat/src/main/java/nextstep/jwp/presentation/FrontController.java rename tomcat/src/main/java/{org/apache/coyote/http11 => nextstep/jwp/presentation}/HomeController.java (75%) create mode 100644 tomcat/src/main/java/nextstep/jwp/presentation/LoginController.java rename tomcat/src/main/java/{org/apache/coyote/http11 => nextstep/jwp/presentation}/RegisterController.java (79%) rename tomcat/src/main/java/{org/apache/coyote/http11 => nextstep/jwp/presentation}/RequestMapping.java (92%) rename tomcat/src/main/java/{org/apache/coyote/http11 => nextstep/jwp/presentation}/ResourceController.java (85%) create mode 100644 tomcat/src/main/java/nextstep/jwp/service/LoginService.java delete mode 100644 tomcat/src/main/java/org/apache/coyote/http11/Controller.java rename tomcat/src/main/java/org/apache/coyote/http11/{ExceptionHandler.java => HttpExceptionHandler.java} (88%) delete mode 100644 tomcat/src/main/java/org/apache/coyote/http11/LoginController.java diff --git a/tomcat/src/main/java/org/apache/coyote/http11/FormData.java b/tomcat/src/main/java/nextstep/jwp/common/FormData.java similarity index 82% rename from tomcat/src/main/java/org/apache/coyote/http11/FormData.java rename to tomcat/src/main/java/nextstep/jwp/common/FormData.java index cda32bf1a2..802a2e8e5d 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/FormData.java +++ b/tomcat/src/main/java/nextstep/jwp/common/FormData.java @@ -1,9 +1,10 @@ -package org.apache.coyote.http11; +package nextstep.jwp.common; -import static org.apache.coyote.http11.HttpStatus.BAD_REQUEST; +import static nextstep.jwp.exception.AuthExceptionType.INVALID_FORM; import java.util.HashMap; import java.util.Map; +import nextstep.jwp.exception.AuthException; public class FormData { @@ -32,6 +33,6 @@ public String get(String key) { if (formTable.containsKey(key)) { return formTable.get(key); } - throw new HttpException(BAD_REQUEST, "데이터가 존재하지 않습니다"); + throw new AuthException(INVALID_FORM); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/ResourceLoader.java b/tomcat/src/main/java/nextstep/jwp/common/ResourceLoader.java similarity index 61% rename from tomcat/src/main/java/org/apache/coyote/http11/ResourceLoader.java rename to tomcat/src/main/java/nextstep/jwp/common/ResourceLoader.java index 81538c3d98..301c1249d6 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/ResourceLoader.java +++ b/tomcat/src/main/java/nextstep/jwp/common/ResourceLoader.java @@ -1,25 +1,26 @@ -package org.apache.coyote.http11; +package nextstep.jwp.common; -import static org.apache.coyote.http11.HttpStatus.BAD_REQUEST; +import static nextstep.jwp.exception.ResourceExceptionType.RESOURCE_NOT_FOUND; import java.io.File; import java.io.IOException; import java.net.URL; import java.nio.file.Files; +import nextstep.jwp.exception.ResourceException; public class ResourceLoader { public String load(String path) { URL resource = getClass().getClassLoader().getResource(path); if (resource == null) { - throw new HttpException(BAD_REQUEST, "요청받은 리소스가 존재하지 않습니다"); + throw new ResourceException(RESOURCE_NOT_FOUND); } File file = new File(resource.getFile()); try { byte[] bytes = Files.readAllBytes(file.toPath()); return new String(bytes); } catch (IOException e) { - throw new HttpException(BAD_REQUEST, "요청받은 리소스가 존재하지 않습니다"); + throw new ResourceException(RESOURCE_NOT_FOUND); } } } diff --git a/tomcat/src/main/java/nextstep/jwp/config/ControllerConfig.java b/tomcat/src/main/java/nextstep/jwp/config/ControllerConfig.java new file mode 100644 index 0000000000..357f4ff4f7 --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/config/ControllerConfig.java @@ -0,0 +1,37 @@ +package nextstep.jwp.config; + +import nextstep.jwp.common.ResourceLoader; +import nextstep.jwp.presentation.ExceptionControllerAdvice; +import nextstep.jwp.presentation.FrontController; +import nextstep.jwp.presentation.HomeController; +import nextstep.jwp.presentation.LoginController; +import nextstep.jwp.presentation.RegisterController; +import nextstep.jwp.presentation.RequestMapping; +import nextstep.jwp.presentation.ResourceController; +import nextstep.jwp.service.LoginService; +import org.apache.catalina.SessionManager; + +public class ControllerConfig { + + public static final ExceptionControllerAdvice exceptionControllerAdvice = new ExceptionControllerAdvice(); + private static final ResourceLoader resourceLoader = new ResourceLoader(); + private static final SessionManager sessionManager = new SessionManager(); + private static final LoginService loginService = new LoginService(sessionManager); + private static final LoginController loginController = new LoginController(resourceLoader, loginService); + private static final HomeController homeController = new HomeController(); + private static final RegisterController registerController = new RegisterController(resourceLoader); + private static final ResourceController resourceController = new ResourceController(resourceLoader); + private static final RequestMapping requestMapping = new RequestMapping( + homeController, + loginController, + registerController, + resourceController + ); + public static final FrontController frontController = new FrontController( + requestMapping, + exceptionControllerAdvice + ); + + private ControllerConfig() { + } +} diff --git a/tomcat/src/main/java/nextstep/jwp/exception/AuthException.java b/tomcat/src/main/java/nextstep/jwp/exception/AuthException.java new file mode 100644 index 0000000000..c9c0019f46 --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/exception/AuthException.java @@ -0,0 +1,15 @@ +package nextstep.jwp.exception; + +public class AuthException extends BaseException { + + private final AuthExceptionType exceptionType; + + public AuthException(AuthExceptionType exceptionType) { + this.exceptionType = exceptionType; + } + + @Override + public BaseExceptionType exceptionType() { + return exceptionType; + } +} diff --git a/tomcat/src/main/java/nextstep/jwp/exception/AuthExceptionType.java b/tomcat/src/main/java/nextstep/jwp/exception/AuthExceptionType.java new file mode 100644 index 0000000000..3a9a57afc0 --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/exception/AuthExceptionType.java @@ -0,0 +1,34 @@ +package nextstep.jwp.exception; + +import static org.apache.coyote.http11.HttpStatus.BAD_REQUEST; +import static org.apache.coyote.http11.HttpStatus.UNAUTHORIZED; + +import org.apache.coyote.http11.HttpStatus; + +public enum AuthExceptionType implements BaseExceptionType { + + INVALID_SESSION_ID(UNAUTHORIZED, "잘못된 세션 아이디입니다"), + USER_NO_EXIST_IN_SESSION(UNAUTHORIZED, "세션에 회원정보가 존재하지 않습니다"), + INVALID_ID_OR_PASSWORD(UNAUTHORIZED, "아이디나 비밀번호를 확인해주세요"), + DUPLICATED_ID(BAD_REQUEST, "이미 존재하는 아이디입니다. 다른 아이디로 가입해주세요"), + INVALID_FORM(BAD_REQUEST, "데이터가 존재하지 않습니다"), + ; + + private final HttpStatus httpStatus; + private final String errorMessage; + + AuthExceptionType(HttpStatus httpStatus, String errorMessage) { + this.httpStatus = httpStatus; + this.errorMessage = errorMessage; + } + + @Override + public HttpStatus httpStatus() { + return httpStatus; + } + + @Override + public String errorMessage() { + return errorMessage; + } +} diff --git a/tomcat/src/main/java/nextstep/jwp/exception/BaseException.java b/tomcat/src/main/java/nextstep/jwp/exception/BaseException.java new file mode 100644 index 0000000000..3bde1bade5 --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/exception/BaseException.java @@ -0,0 +1,9 @@ +package nextstep.jwp.exception; + +public abstract class BaseException extends RuntimeException { + + public BaseException() { + } + + public abstract BaseExceptionType exceptionType(); +} diff --git a/tomcat/src/main/java/nextstep/jwp/exception/BaseExceptionType.java b/tomcat/src/main/java/nextstep/jwp/exception/BaseExceptionType.java new file mode 100644 index 0000000000..2604c0742a --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/exception/BaseExceptionType.java @@ -0,0 +1,10 @@ +package nextstep.jwp.exception; + +import org.apache.coyote.http11.HttpStatus; + +public interface BaseExceptionType { + + HttpStatus httpStatus(); + + String errorMessage(); +} diff --git a/tomcat/src/main/java/nextstep/jwp/exception/ControllerException.java b/tomcat/src/main/java/nextstep/jwp/exception/ControllerException.java new file mode 100644 index 0000000000..284972c360 --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/exception/ControllerException.java @@ -0,0 +1,15 @@ +package nextstep.jwp.exception; + +public class ControllerException extends BaseException { + + private final ControllerExceptionType exceptionType; + + public ControllerException(ControllerExceptionType exceptionType) { + this.exceptionType = exceptionType; + } + + @Override + public BaseExceptionType exceptionType() { + return exceptionType; + } +} diff --git a/tomcat/src/main/java/nextstep/jwp/exception/ControllerExceptionType.java b/tomcat/src/main/java/nextstep/jwp/exception/ControllerExceptionType.java new file mode 100644 index 0000000000..872fcfd252 --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/exception/ControllerExceptionType.java @@ -0,0 +1,30 @@ +package nextstep.jwp.exception; + +import static org.apache.coyote.http11.HttpStatus.BAD_REQUEST; + +import org.apache.coyote.http11.HttpStatus; + +public enum ControllerExceptionType implements BaseExceptionType { + + UNSUPPORTED_REQUEST(BAD_REQUEST, "지원되지 않는 요청입니다"), + UNSUPPORTED_METHOD(BAD_REQUEST, "존재하지 않는 메서드입니다"), + ; + + private final HttpStatus httpStatus; + private final String errorMessage; + + ControllerExceptionType(HttpStatus httpStatus, String errorMessage) { + this.httpStatus = httpStatus; + this.errorMessage = errorMessage; + } + + @Override + public HttpStatus httpStatus() { + return httpStatus; + } + + @Override + public String errorMessage() { + return errorMessage; + } +} diff --git a/tomcat/src/main/java/nextstep/jwp/exception/ResourceException.java b/tomcat/src/main/java/nextstep/jwp/exception/ResourceException.java new file mode 100644 index 0000000000..31830b62be --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/exception/ResourceException.java @@ -0,0 +1,15 @@ +package nextstep.jwp.exception; + +public class ResourceException extends BaseException { + + private final ResourceExceptionType exceptionType; + + public ResourceException(ResourceExceptionType exceptionType) { + this.exceptionType = exceptionType; + } + + @Override + public BaseExceptionType exceptionType() { + return exceptionType; + } +} diff --git a/tomcat/src/main/java/nextstep/jwp/exception/ResourceExceptionType.java b/tomcat/src/main/java/nextstep/jwp/exception/ResourceExceptionType.java new file mode 100644 index 0000000000..cdaf1eb128 --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/exception/ResourceExceptionType.java @@ -0,0 +1,29 @@ +package nextstep.jwp.exception; + +import static org.apache.coyote.http11.HttpStatus.BAD_REQUEST; + +import org.apache.coyote.http11.HttpStatus; + +public enum ResourceExceptionType implements BaseExceptionType { + + RESOURCE_NOT_FOUND(BAD_REQUEST, "요청받은 리소스가 존재하지 않습니다"), + ; + + private final HttpStatus httpStatus; + private final String errorMessage; + + ResourceExceptionType(HttpStatus httpStatus, String errorMessage) { + this.httpStatus = httpStatus; + this.errorMessage = errorMessage; + } + + @Override + public HttpStatus httpStatus() { + return httpStatus; + } + + @Override + public String errorMessage() { + return errorMessage; + } +} diff --git a/tomcat/src/main/java/org/apache/coyote/http11/AbstractController.java b/tomcat/src/main/java/nextstep/jwp/presentation/AbstractController.java similarity index 55% rename from tomcat/src/main/java/org/apache/coyote/http11/AbstractController.java rename to tomcat/src/main/java/nextstep/jwp/presentation/AbstractController.java index 4dab0acac9..f77d5f7376 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/AbstractController.java +++ b/tomcat/src/main/java/nextstep/jwp/presentation/AbstractController.java @@ -1,8 +1,12 @@ -package org.apache.coyote.http11; +package nextstep.jwp.presentation; +import static nextstep.jwp.exception.ControllerExceptionType.UNSUPPORTED_REQUEST; import static org.apache.coyote.http11.HttpMethod.GET; import static org.apache.coyote.http11.HttpMethod.POST; -import static org.apache.coyote.http11.HttpStatus.BAD_REQUEST; + +import nextstep.jwp.exception.ControllerException; +import org.apache.coyote.http11.HttpRequest; +import org.apache.coyote.http11.HttpResponse; public abstract class AbstractController implements Controller { @@ -14,14 +18,14 @@ public HttpResponse service(HttpRequest request) { if (request.method() == GET) { return doGet(request); } - throw new HttpException(BAD_REQUEST, "지원되지 않는 요청입니다"); + throw new ControllerException(UNSUPPORTED_REQUEST); } protected HttpResponse doPost(HttpRequest request) { - throw new HttpException(BAD_REQUEST, "지원되지 않는 요청입니다"); + throw new ControllerException(UNSUPPORTED_REQUEST); } protected HttpResponse doGet(HttpRequest request) { - throw new HttpException(BAD_REQUEST, "지원되지 않는 요청입니다"); + throw new ControllerException(UNSUPPORTED_REQUEST); } } diff --git a/tomcat/src/main/java/nextstep/jwp/presentation/Controller.java b/tomcat/src/main/java/nextstep/jwp/presentation/Controller.java new file mode 100644 index 0000000000..76bd808a1c --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/presentation/Controller.java @@ -0,0 +1,9 @@ +package nextstep.jwp.presentation; + +import org.apache.coyote.http11.HttpRequest; +import org.apache.coyote.http11.HttpResponse; + +public interface Controller { + + HttpResponse service(HttpRequest request); +} diff --git a/tomcat/src/main/java/nextstep/jwp/presentation/ExceptionControllerAdvice.java b/tomcat/src/main/java/nextstep/jwp/presentation/ExceptionControllerAdvice.java new file mode 100644 index 0000000000..c01bb851f0 --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/presentation/ExceptionControllerAdvice.java @@ -0,0 +1,24 @@ +package nextstep.jwp.presentation; + +import static org.apache.coyote.http11.ContentType.TEXT_HTML; + +import nextstep.jwp.common.ResourceLoader; +import nextstep.jwp.exception.BaseException; +import org.apache.coyote.http11.HttpResponse; +import org.apache.coyote.http11.HttpStatus; + +public class ExceptionControllerAdvice { + + private static final String RESOURCE_PATH_FORMAT = "static/%s.html"; + + HttpResponse handleException(BaseException e) { + HttpStatus httpStatus = e.exceptionType().httpStatus(); + int code = httpStatus.statusCode(); + ResourceLoader resourceLoader = new ResourceLoader(); + String body = resourceLoader.load(String.format(RESOURCE_PATH_FORMAT, code)); + return HttpResponse.status(httpStatus) + .contentType(TEXT_HTML) + .body(body) + .build(); + } +} diff --git a/tomcat/src/main/java/nextstep/jwp/presentation/FrontController.java b/tomcat/src/main/java/nextstep/jwp/presentation/FrontController.java new file mode 100644 index 0000000000..8bad84c5b3 --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/presentation/FrontController.java @@ -0,0 +1,25 @@ +package nextstep.jwp.presentation; + +import nextstep.jwp.exception.BaseException; +import org.apache.coyote.http11.HttpRequest; +import org.apache.coyote.http11.HttpResponse; + +public class FrontController { + + private final RequestMapping requestMapping; + private final ExceptionControllerAdvice exceptionControllerAdvice; + + public FrontController(RequestMapping requestMapping, ExceptionControllerAdvice exceptionControllerAdvice) { + this.requestMapping = requestMapping; + this.exceptionControllerAdvice = exceptionControllerAdvice; + } + + public HttpResponse service(HttpRequest request) { + try { + Controller controller = requestMapping.getController(request); + return controller.service(request); + } catch (BaseException e) { + return exceptionControllerAdvice.handleException(e); + } + } +} diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HomeController.java b/tomcat/src/main/java/nextstep/jwp/presentation/HomeController.java similarity index 75% rename from tomcat/src/main/java/org/apache/coyote/http11/HomeController.java rename to tomcat/src/main/java/nextstep/jwp/presentation/HomeController.java index 41025b6990..d3a816a4a0 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/HomeController.java +++ b/tomcat/src/main/java/nextstep/jwp/presentation/HomeController.java @@ -1,8 +1,11 @@ -package org.apache.coyote.http11; +package nextstep.jwp.presentation; import static org.apache.coyote.http11.ContentType.TEXT_HTML; import static org.apache.coyote.http11.HttpStatus.OK; +import org.apache.coyote.http11.HttpRequest; +import org.apache.coyote.http11.HttpResponse; + public class HomeController extends AbstractController { @Override diff --git a/tomcat/src/main/java/nextstep/jwp/presentation/LoginController.java b/tomcat/src/main/java/nextstep/jwp/presentation/LoginController.java new file mode 100644 index 0000000000..8f2759530c --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/presentation/LoginController.java @@ -0,0 +1,44 @@ +package nextstep.jwp.presentation; + +import static org.apache.coyote.http11.ContentType.TEXT_HTML; +import static org.apache.coyote.http11.HttpStatus.OK; + +import java.util.Optional; +import nextstep.jwp.common.ResourceLoader; +import nextstep.jwp.service.LoginService; +import org.apache.coyote.http11.HttpRequest; +import org.apache.coyote.http11.HttpResponse; + +public class LoginController extends AbstractController { + + private static final String JSESSIONID = "JSESSIONID"; + + private final ResourceLoader resourceLoader; + private final LoginService loginService; + + public LoginController(ResourceLoader resourceLoader, LoginService loginService) { + this.resourceLoader = resourceLoader; + this.loginService = loginService; + } + + @Override + protected HttpResponse doPost(HttpRequest request) { + Optional jsessionid = request.getCookie(JSESSIONID); + if (jsessionid.isPresent()) { + return loginService.loginWithSession(jsessionid.get()); + } + return loginService.login(request); + } + + @Override + protected HttpResponse doGet(HttpRequest request) { + Optional jsessionid = request.getCookie(JSESSIONID); + if (jsessionid.isPresent()) { + return loginService.loginWithSession(jsessionid.get()); + } + return HttpResponse.status(OK) + .body(resourceLoader.load("static/login.html")) + .contentType(TEXT_HTML) + .build(); + } +} diff --git a/tomcat/src/main/java/org/apache/coyote/http11/RegisterController.java b/tomcat/src/main/java/nextstep/jwp/presentation/RegisterController.java similarity index 79% rename from tomcat/src/main/java/org/apache/coyote/http11/RegisterController.java rename to tomcat/src/main/java/nextstep/jwp/presentation/RegisterController.java index 6a1e24672c..8135f76bf8 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/RegisterController.java +++ b/tomcat/src/main/java/nextstep/jwp/presentation/RegisterController.java @@ -1,12 +1,17 @@ -package org.apache.coyote.http11; +package nextstep.jwp.presentation; +import static nextstep.jwp.exception.AuthExceptionType.DUPLICATED_ID; import static org.apache.coyote.http11.ContentType.TEXT_HTML; -import static org.apache.coyote.http11.HttpStatus.BAD_REQUEST; import static org.apache.coyote.http11.HttpStatus.FOUND; import static org.apache.coyote.http11.HttpStatus.OK; +import nextstep.jwp.common.FormData; +import nextstep.jwp.common.ResourceLoader; import nextstep.jwp.db.InMemoryUserRepository; +import nextstep.jwp.exception.AuthException; import nextstep.jwp.model.User; +import org.apache.coyote.http11.HttpRequest; +import org.apache.coyote.http11.HttpResponse; public class RegisterController extends AbstractController { @@ -17,7 +22,7 @@ public class RegisterController extends AbstractController { public RegisterController(ResourceLoader resourceLoader) { this.resourceLoader = resourceLoader; } - + @Override protected HttpResponse doPost(HttpRequest request) { return register(request); @@ -37,7 +42,7 @@ private HttpResponse register(HttpRequest request) { String password = formData.get("password"); String email = formData.get("email"); if (InMemoryUserRepository.findByAccount(account).isPresent()) { - throw new HttpException(BAD_REQUEST, "이미 존재하는 아이디입니다. 다른 아이디로 가입해주세요"); + throw new AuthException(DUPLICATED_ID); } User user = new User(account, password, email); InMemoryUserRepository.save(user); diff --git a/tomcat/src/main/java/org/apache/coyote/http11/RequestMapping.java b/tomcat/src/main/java/nextstep/jwp/presentation/RequestMapping.java similarity index 92% rename from tomcat/src/main/java/org/apache/coyote/http11/RequestMapping.java rename to tomcat/src/main/java/nextstep/jwp/presentation/RequestMapping.java index 9d14883496..7467d27f64 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/RequestMapping.java +++ b/tomcat/src/main/java/nextstep/jwp/presentation/RequestMapping.java @@ -1,4 +1,6 @@ -package org.apache.coyote.http11; +package nextstep.jwp.presentation; + +import org.apache.coyote.http11.HttpRequest; public class RequestMapping { diff --git a/tomcat/src/main/java/org/apache/coyote/http11/ResourceController.java b/tomcat/src/main/java/nextstep/jwp/presentation/ResourceController.java similarity index 85% rename from tomcat/src/main/java/org/apache/coyote/http11/ResourceController.java rename to tomcat/src/main/java/nextstep/jwp/presentation/ResourceController.java index d6f5b07408..cabe03ad02 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/ResourceController.java +++ b/tomcat/src/main/java/nextstep/jwp/presentation/ResourceController.java @@ -1,10 +1,13 @@ -package org.apache.coyote.http11; +package nextstep.jwp.presentation; import static org.apache.coyote.http11.ContentType.TEXT_CSS; import static org.apache.coyote.http11.ContentType.TEXT_HTML; import static org.apache.coyote.http11.HttpStatus.OK; import java.util.Optional; +import nextstep.jwp.common.ResourceLoader; +import org.apache.coyote.http11.HttpRequest; +import org.apache.coyote.http11.HttpResponse; public class ResourceController extends AbstractController { diff --git a/tomcat/src/main/java/nextstep/jwp/service/LoginService.java b/tomcat/src/main/java/nextstep/jwp/service/LoginService.java new file mode 100644 index 0000000000..102c785843 --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/service/LoginService.java @@ -0,0 +1,58 @@ +package nextstep.jwp.service; + +import static nextstep.jwp.exception.AuthExceptionType.INVALID_ID_OR_PASSWORD; +import static nextstep.jwp.exception.AuthExceptionType.INVALID_SESSION_ID; +import static nextstep.jwp.exception.AuthExceptionType.USER_NO_EXIST_IN_SESSION; +import static org.apache.coyote.http11.HttpStatus.FOUND; + +import java.util.Optional; +import java.util.UUID; +import nextstep.jwp.common.FormData; +import nextstep.jwp.db.InMemoryUserRepository; +import nextstep.jwp.exception.AuthException; +import nextstep.jwp.model.User; +import org.apache.catalina.Session; +import org.apache.catalina.SessionManager; +import org.apache.coyote.http11.HttpRequest; +import org.apache.coyote.http11.HttpResponse; + +public class LoginService { + + private static final String JSESSIONID = "JSESSIONID"; + private static final String INDEX_HTML = "/index.html"; + + private final SessionManager sessionManager; + + public LoginService(SessionManager sessionManager) { + this.sessionManager = sessionManager; + } + + public HttpResponse loginWithSession(String jsessionid) { + Session session = sessionManager.findSession(jsessionid) + .orElseThrow(() -> new AuthException(INVALID_SESSION_ID)); + if (session.getAttribute("user").isEmpty()) { + throw new AuthException(USER_NO_EXIST_IN_SESSION); + } + return HttpResponse.status(FOUND) + .redirectUri(INDEX_HTML) + .build(); + } + + public HttpResponse login(HttpRequest httpRequest) { + FormData formData = FormData.from(httpRequest.getBody()); + String account = formData.get("account"); + String password = formData.get("password"); + Optional user = InMemoryUserRepository.findByAccount(account); + if (user.isPresent() && user.get().checkPassword(password)) { + String jsessionid = UUID.randomUUID().toString(); + Session session = new Session(jsessionid); + session.setAttribute("user", user.get()); + sessionManager.add(session); + return HttpResponse.status(FOUND) + .redirectUri(INDEX_HTML) + .cookie(JSESSIONID, jsessionid) + .build(); + } + throw new AuthException(INVALID_ID_OR_PASSWORD); + } +} diff --git a/tomcat/src/main/java/org/apache/coyote/http11/Controller.java b/tomcat/src/main/java/org/apache/coyote/http11/Controller.java deleted file mode 100644 index c783407f30..0000000000 --- a/tomcat/src/main/java/org/apache/coyote/http11/Controller.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.apache.coyote.http11; - -public interface Controller { - - HttpResponse service(HttpRequest request); -} diff --git a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java index c8dfb68363..104fa0b79e 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java @@ -6,8 +6,9 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.net.Socket; +import nextstep.jwp.config.ControllerConfig; import nextstep.jwp.exception.UncheckedServletException; -import org.apache.catalina.SessionManager; +import nextstep.jwp.presentation.FrontController; import org.apache.coyote.Processor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -17,18 +18,11 @@ public class Http11Processor implements Runnable, Processor { private static final Logger log = LoggerFactory.getLogger(Http11Processor.class); private final Socket connection; - private final RequestMapping requestMapping; + private final FrontController frontController; public Http11Processor(Socket connection) { this.connection = connection; - SessionManager sessionManager = new SessionManager(); - ResourceLoader resourceLoader = new ResourceLoader(); - requestMapping = new RequestMapping( - new HomeController(), - new LoginController(resourceLoader, sessionManager), - new RegisterController(resourceLoader), - new ResourceController(resourceLoader) - ); + frontController = ControllerConfig.frontController; } @Override @@ -52,13 +46,12 @@ public void process(final Socket connection) { } private HttpResponse process(BufferedReader bufferedReader) { - ExceptionHandler exceptionHandler = new ExceptionHandler(); + HttpExceptionHandler httpExceptionHandler = new HttpExceptionHandler(); try { HttpRequest httpRequest = HttpRequest.from(bufferedReader); - Controller controller = requestMapping.getController(httpRequest); - return controller.service(httpRequest); + return frontController.service(httpRequest); } catch (HttpException e) { - return exceptionHandler.handleException(e); + return httpExceptionHandler.handleException(e); } } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/ExceptionHandler.java b/tomcat/src/main/java/org/apache/coyote/http11/HttpExceptionHandler.java similarity index 88% rename from tomcat/src/main/java/org/apache/coyote/http11/ExceptionHandler.java rename to tomcat/src/main/java/org/apache/coyote/http11/HttpExceptionHandler.java index fc7d2b0f46..d470927256 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/ExceptionHandler.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/HttpExceptionHandler.java @@ -2,7 +2,9 @@ import static org.apache.coyote.http11.ContentType.TEXT_HTML; -public class ExceptionHandler { +import nextstep.jwp.common.ResourceLoader; + +public class HttpExceptionHandler { private static final String RESOURCE_PATH_FORMAT = "static/%s.html"; diff --git a/tomcat/src/main/java/org/apache/coyote/http11/LoginController.java b/tomcat/src/main/java/org/apache/coyote/http11/LoginController.java deleted file mode 100644 index 53f81159db..0000000000 --- a/tomcat/src/main/java/org/apache/coyote/http11/LoginController.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.apache.coyote.http11; - -import static org.apache.coyote.http11.ContentType.TEXT_HTML; -import static org.apache.coyote.http11.HttpStatus.FOUND; -import static org.apache.coyote.http11.HttpStatus.OK; -import static org.apache.coyote.http11.HttpStatus.UNAUTHORIZED; - -import java.util.Optional; -import java.util.UUID; -import nextstep.jwp.db.InMemoryUserRepository; -import nextstep.jwp.model.User; -import org.apache.catalina.Session; -import org.apache.catalina.SessionManager; - -public class LoginController extends AbstractController { - - private static final String JSESSIONID = "JSESSIONID"; - private static final String INDEX_HTML = "/index.html"; - - private final ResourceLoader resourceLoader; - private final SessionManager sessionManager; - - public LoginController(ResourceLoader resourceLoader, SessionManager sessionManager) { - this.resourceLoader = resourceLoader; - this.sessionManager = sessionManager; - } - - @Override - protected HttpResponse doPost(HttpRequest request) { - Optional jsessionid = request.getCookie(JSESSIONID); - if (jsessionid.isPresent()) { - return loginWithSession(jsessionid.get()); - } - return login(request); - } - - @Override - protected HttpResponse doGet(HttpRequest request) { - Optional jsessionid = request.getCookie(JSESSIONID); - if (jsessionid.isPresent()) { - return loginWithSession(jsessionid.get()); - } - return HttpResponse.status(OK) - .body(resourceLoader.load("static/login.html")) - .contentType(TEXT_HTML) - .build(); - } - - private HttpResponse loginWithSession(String jsessionid) { - Session session = sessionManager.findSession(jsessionid) - .orElseThrow(() -> new HttpException(UNAUTHORIZED, "잘못된 세션 아이디입니다")); - if (session.getAttribute("user").isEmpty()) { - throw new HttpException(UNAUTHORIZED, "세션에 회원정보가 존재하지 않습니다"); - } - return HttpResponse.status(FOUND) - .redirectUri(INDEX_HTML) - .build(); - } - - private HttpResponse login(HttpRequest httpRequest) { - FormData formData = FormData.from(httpRequest.getBody()); - String account = formData.get("account"); - String password = formData.get("password"); - Optional user = InMemoryUserRepository.findByAccount(account); - if (user.isPresent() && user.get().checkPassword(password)) { - String jsessionid = UUID.randomUUID().toString(); - Session session = new Session(jsessionid); - session.setAttribute("user", user.get()); - sessionManager.add(session); - return HttpResponse.status(FOUND) - .redirectUri(INDEX_HTML) - .cookie(JSESSIONID, jsessionid) - .build(); - } - throw new HttpException(UNAUTHORIZED, "아이디나 비밀번호를 확인해주세요"); - } -} From d56256a784f4f41f31d60873639c053632b6139f Mon Sep 17 00:00:00 2001 From: odo27 Date: Sun, 10 Sep 2023 20:45:54 +0900 Subject: [PATCH 04/10] =?UTF-8?q?feat:=20=EC=93=B0=EB=A0=88=EB=93=9C?= =?UTF-8?q?=ED=92=80=20=EB=B0=8F=20=EB=8F=99=EC=8B=9C=EC=84=B1=20=EC=BB=AC?= =?UTF-8?q?=EB=A0=89=EC=85=98=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/apache/catalina/SessionManager.java | 4 ++-- .../apache/catalina/connector/Connector.java | 18 +++++++++++------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/tomcat/src/main/java/org/apache/catalina/SessionManager.java b/tomcat/src/main/java/org/apache/catalina/SessionManager.java index ad4dadcb3c..e975d4d7d9 100644 --- a/tomcat/src/main/java/org/apache/catalina/SessionManager.java +++ b/tomcat/src/main/java/org/apache/catalina/SessionManager.java @@ -1,12 +1,12 @@ package org.apache.catalina; -import java.util.HashMap; import java.util.Map; import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; public class SessionManager { - private static final Map SESSIONS = new HashMap<>(); + private static final Map SESSIONS = new ConcurrentHashMap<>(); public void add(Session session) { SESSIONS.put(session.getId(), session); diff --git a/tomcat/src/main/java/org/apache/catalina/connector/Connector.java b/tomcat/src/main/java/org/apache/catalina/connector/Connector.java index 3b2c4dda7c..371be7bb4c 100644 --- a/tomcat/src/main/java/org/apache/catalina/connector/Connector.java +++ b/tomcat/src/main/java/org/apache/catalina/connector/Connector.java @@ -1,13 +1,14 @@ package org.apache.catalina.connector; -import org.apache.coyote.http11.Http11Processor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.io.IOException; import java.io.UncheckedIOException; import java.net.ServerSocket; import java.net.Socket; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import org.apache.coyote.http11.Http11Processor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class Connector implements Runnable { @@ -15,17 +16,20 @@ public class Connector implements Runnable { private static final int DEFAULT_PORT = 8080; private static final int DEFAULT_ACCEPT_COUNT = 100; + private static final int DEFAULT_MAX_THREAD_COUNT = 250; private final ServerSocket serverSocket; + private final Executor executor; private boolean stopped; public Connector() { - this(DEFAULT_PORT, DEFAULT_ACCEPT_COUNT); + this(DEFAULT_PORT, DEFAULT_ACCEPT_COUNT, DEFAULT_MAX_THREAD_COUNT); } - public Connector(final int port, final int acceptCount) { + public Connector(int port, int acceptCount, int maxThreadCount) { this.serverSocket = createServerSocket(port, acceptCount); this.stopped = false; + this.executor = Executors.newFixedThreadPool(maxThreadCount); } private ServerSocket createServerSocket(final int port, final int acceptCount) { @@ -67,7 +71,7 @@ private void process(final Socket connection) { return; } var processor = new Http11Processor(connection); - new Thread(processor).start(); + executor.execute(processor); } public void stop() { From 26db0d310faf9c9cf21512d681dd42a4a222c0ae Mon Sep 17 00:00:00 2001 From: odo27 Date: Mon, 11 Sep 2023 01:04:11 +0900 Subject: [PATCH 05/10] =?UTF-8?q?refactor:=20Controller=20=EC=9D=B8?= =?UTF-8?q?=ED=84=B0=ED=8E=98=EC=9D=B4=EC=8A=A4=20service=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=8B=9C=EA=B7=B8=EB=8B=88=EC=B2=98=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jwp/presentation/AbstractController.java | 14 +-- .../nextstep/jwp/presentation/Controller.java | 2 +- .../ExceptionControllerAdvice.java | 9 +- .../jwp/presentation/FrontController.java | 6 +- .../jwp/presentation/HomeController.java | 9 +- .../jwp/presentation/LoginController.java | 19 ++-- .../jwp/presentation/RegisterController.java | 20 ++-- .../jwp/presentation/ResourceController.java | 16 ++- .../nextstep/jwp/service/LoginService.java | 17 ++- .../apache/coyote/http11/Http11Processor.java | 14 ++- .../coyote/http11/HttpExceptionHandler.java | 19 +++- .../apache/coyote/http11/HttpResponse.java | 102 ++++++------------ .../org/apache/coyote/http11/HttpStatus.java | 1 + 13 files changed, 112 insertions(+), 136 deletions(-) diff --git a/tomcat/src/main/java/nextstep/jwp/presentation/AbstractController.java b/tomcat/src/main/java/nextstep/jwp/presentation/AbstractController.java index f77d5f7376..451b5a20be 100644 --- a/tomcat/src/main/java/nextstep/jwp/presentation/AbstractController.java +++ b/tomcat/src/main/java/nextstep/jwp/presentation/AbstractController.java @@ -11,21 +11,21 @@ public abstract class AbstractController implements Controller { @Override - public HttpResponse service(HttpRequest request) { + public void service(HttpRequest request, HttpResponse response) throws Exception { if (request.method() == POST) { - return doPost(request); + doPost(request, response); + return; } if (request.method() == GET) { - return doGet(request); + doGet(request, response); + return; } throw new ControllerException(UNSUPPORTED_REQUEST); } - protected HttpResponse doPost(HttpRequest request) { - throw new ControllerException(UNSUPPORTED_REQUEST); + protected void doPost(HttpRequest request, HttpResponse response) throws Exception { } - protected HttpResponse doGet(HttpRequest request) { - throw new ControllerException(UNSUPPORTED_REQUEST); + protected void doGet(HttpRequest request, HttpResponse response) throws Exception { } } diff --git a/tomcat/src/main/java/nextstep/jwp/presentation/Controller.java b/tomcat/src/main/java/nextstep/jwp/presentation/Controller.java index 76bd808a1c..cd8dac0fbe 100644 --- a/tomcat/src/main/java/nextstep/jwp/presentation/Controller.java +++ b/tomcat/src/main/java/nextstep/jwp/presentation/Controller.java @@ -5,5 +5,5 @@ public interface Controller { - HttpResponse service(HttpRequest request); + void service(HttpRequest request, HttpResponse response) throws Exception; } diff --git a/tomcat/src/main/java/nextstep/jwp/presentation/ExceptionControllerAdvice.java b/tomcat/src/main/java/nextstep/jwp/presentation/ExceptionControllerAdvice.java index c01bb851f0..6fa8b68f4e 100644 --- a/tomcat/src/main/java/nextstep/jwp/presentation/ExceptionControllerAdvice.java +++ b/tomcat/src/main/java/nextstep/jwp/presentation/ExceptionControllerAdvice.java @@ -11,14 +11,13 @@ public class ExceptionControllerAdvice { private static final String RESOURCE_PATH_FORMAT = "static/%s.html"; - HttpResponse handleException(BaseException e) { + void handleException(BaseException e, HttpResponse response) { HttpStatus httpStatus = e.exceptionType().httpStatus(); + response.setStatus(httpStatus); int code = httpStatus.statusCode(); ResourceLoader resourceLoader = new ResourceLoader(); String body = resourceLoader.load(String.format(RESOURCE_PATH_FORMAT, code)); - return HttpResponse.status(httpStatus) - .contentType(TEXT_HTML) - .body(body) - .build(); + response.setBody(body); + response.setHeader("Content-Type", TEXT_HTML.value()); } } diff --git a/tomcat/src/main/java/nextstep/jwp/presentation/FrontController.java b/tomcat/src/main/java/nextstep/jwp/presentation/FrontController.java index 8bad84c5b3..78b1b762a0 100644 --- a/tomcat/src/main/java/nextstep/jwp/presentation/FrontController.java +++ b/tomcat/src/main/java/nextstep/jwp/presentation/FrontController.java @@ -14,12 +14,12 @@ public FrontController(RequestMapping requestMapping, ExceptionControllerAdvice this.exceptionControllerAdvice = exceptionControllerAdvice; } - public HttpResponse service(HttpRequest request) { + public void service(HttpRequest request, HttpResponse response) throws Exception { try { Controller controller = requestMapping.getController(request); - return controller.service(request); + controller.service(request, response); } catch (BaseException e) { - return exceptionControllerAdvice.handleException(e); + exceptionControllerAdvice.handleException(e, response); } } } diff --git a/tomcat/src/main/java/nextstep/jwp/presentation/HomeController.java b/tomcat/src/main/java/nextstep/jwp/presentation/HomeController.java index d3a816a4a0..68cd318024 100644 --- a/tomcat/src/main/java/nextstep/jwp/presentation/HomeController.java +++ b/tomcat/src/main/java/nextstep/jwp/presentation/HomeController.java @@ -9,10 +9,9 @@ public class HomeController extends AbstractController { @Override - protected HttpResponse doGet(HttpRequest request) { - return HttpResponse.status(OK) - .body("Hello world!") - .contentType(TEXT_HTML) - .build(); + protected void doGet(HttpRequest request, HttpResponse response) { + response.setStatus(OK); + response.setContentType(TEXT_HTML); + response.setBody("Hello world!"); } } diff --git a/tomcat/src/main/java/nextstep/jwp/presentation/LoginController.java b/tomcat/src/main/java/nextstep/jwp/presentation/LoginController.java index 8f2759530c..4aef916b64 100644 --- a/tomcat/src/main/java/nextstep/jwp/presentation/LoginController.java +++ b/tomcat/src/main/java/nextstep/jwp/presentation/LoginController.java @@ -22,23 +22,24 @@ public LoginController(ResourceLoader resourceLoader, LoginService loginService) } @Override - protected HttpResponse doPost(HttpRequest request) { + protected void doPost(HttpRequest request, HttpResponse response) { Optional jsessionid = request.getCookie(JSESSIONID); if (jsessionid.isPresent()) { - return loginService.loginWithSession(jsessionid.get()); + loginService.loginWithSession(jsessionid.get(), response); + return; } - return loginService.login(request); + loginService.login(request, response); } @Override - protected HttpResponse doGet(HttpRequest request) { + protected void doGet(HttpRequest request, HttpResponse response) { Optional jsessionid = request.getCookie(JSESSIONID); if (jsessionid.isPresent()) { - return loginService.loginWithSession(jsessionid.get()); + loginService.loginWithSession(jsessionid.get(), response); + return; } - return HttpResponse.status(OK) - .body(resourceLoader.load("static/login.html")) - .contentType(TEXT_HTML) - .build(); + response.setStatus(OK); + response.setContentType(TEXT_HTML); + response.setBody(resourceLoader.load("static/login.html")); } } diff --git a/tomcat/src/main/java/nextstep/jwp/presentation/RegisterController.java b/tomcat/src/main/java/nextstep/jwp/presentation/RegisterController.java index 8135f76bf8..c006c13eee 100644 --- a/tomcat/src/main/java/nextstep/jwp/presentation/RegisterController.java +++ b/tomcat/src/main/java/nextstep/jwp/presentation/RegisterController.java @@ -24,19 +24,18 @@ public RegisterController(ResourceLoader resourceLoader) { } @Override - protected HttpResponse doPost(HttpRequest request) { - return register(request); + protected void doPost(HttpRequest request, HttpResponse response) { + register(request, response); } @Override - protected HttpResponse doGet(HttpRequest request) { - return HttpResponse.status(OK) - .body(resourceLoader.load("static/register.html")) - .contentType(TEXT_HTML) - .build(); + protected void doGet(HttpRequest request, HttpResponse response) { + response.setStatus(OK); + response.setBody(resourceLoader.load("static/register.html")); + response.setContentType(TEXT_HTML); } - private HttpResponse register(HttpRequest request) { + private void register(HttpRequest request, HttpResponse response) { FormData formData = FormData.from(request.getBody()); String account = formData.get("account"); String password = formData.get("password"); @@ -47,8 +46,7 @@ private HttpResponse register(HttpRequest request) { User user = new User(account, password, email); InMemoryUserRepository.save(user); - return HttpResponse.status(FOUND) - .redirectUri(INDEX_HTML) - .build(); + response.setStatus(FOUND); + response.sendRedirect(INDEX_HTML); } } diff --git a/tomcat/src/main/java/nextstep/jwp/presentation/ResourceController.java b/tomcat/src/main/java/nextstep/jwp/presentation/ResourceController.java index cabe03ad02..014b2516b0 100644 --- a/tomcat/src/main/java/nextstep/jwp/presentation/ResourceController.java +++ b/tomcat/src/main/java/nextstep/jwp/presentation/ResourceController.java @@ -18,17 +18,15 @@ public ResourceController(ResourceLoader resourceLoader) { } @Override - protected HttpResponse doGet(HttpRequest request) { + protected void doGet(HttpRequest request, HttpResponse response) { + response.setStatus(OK); Optional acceptHeader = request.getHeader("Accept"); if (acceptHeader.isPresent() && acceptHeader.get().contains("text/css")) { - return HttpResponse.status(OK) - .body(resourceLoader.load("static" + request.uri())) - .contentType(TEXT_CSS) - .build(); + response.setContentType(TEXT_CSS); + response.setBody(resourceLoader.load("static" + request.uri())); + return; } - return HttpResponse.status(OK) - .body(resourceLoader.load("static" + request.uri())) - .contentType(TEXT_HTML) - .build(); + response.setContentType(TEXT_HTML); + response.setBody(resourceLoader.load("static" + request.uri())); } } diff --git a/tomcat/src/main/java/nextstep/jwp/service/LoginService.java b/tomcat/src/main/java/nextstep/jwp/service/LoginService.java index 102c785843..5bd249b743 100644 --- a/tomcat/src/main/java/nextstep/jwp/service/LoginService.java +++ b/tomcat/src/main/java/nextstep/jwp/service/LoginService.java @@ -27,18 +27,17 @@ public LoginService(SessionManager sessionManager) { this.sessionManager = sessionManager; } - public HttpResponse loginWithSession(String jsessionid) { + public void loginWithSession(String jsessionid, HttpResponse response) { Session session = sessionManager.findSession(jsessionid) .orElseThrow(() -> new AuthException(INVALID_SESSION_ID)); if (session.getAttribute("user").isEmpty()) { throw new AuthException(USER_NO_EXIST_IN_SESSION); } - return HttpResponse.status(FOUND) - .redirectUri(INDEX_HTML) - .build(); + response.setStatus(FOUND); + response.sendRedirect(INDEX_HTML); } - public HttpResponse login(HttpRequest httpRequest) { + public void login(HttpRequest httpRequest, HttpResponse response) { FormData formData = FormData.from(httpRequest.getBody()); String account = formData.get("account"); String password = formData.get("password"); @@ -48,10 +47,10 @@ public HttpResponse login(HttpRequest httpRequest) { Session session = new Session(jsessionid); session.setAttribute("user", user.get()); sessionManager.add(session); - return HttpResponse.status(FOUND) - .redirectUri(INDEX_HTML) - .cookie(JSESSIONID, jsessionid) - .build(); + response.setStatus(FOUND); + response.sendRedirect(INDEX_HTML); + response.addCookie(JSESSIONID, jsessionid); + return; } throw new AuthException(INVALID_ID_OR_PASSWORD); } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java index 104fa0b79e..53374f6f04 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java @@ -38,20 +38,24 @@ public void process(final Socket connection) { InputStreamReader inputStreamReader = new InputStreamReader(inputStream); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); - outputStream.write(process(bufferedReader).getBytes()); + HttpResponse response = new HttpResponse(); + process(bufferedReader, response); + outputStream.write(response.getBytes()); outputStream.flush(); } catch (IOException | UncheckedServletException e) { log.error(e.getMessage(), e); } } - private HttpResponse process(BufferedReader bufferedReader) { + private void process(BufferedReader bufferedReader, HttpResponse response) { HttpExceptionHandler httpExceptionHandler = new HttpExceptionHandler(); try { - HttpRequest httpRequest = HttpRequest.from(bufferedReader); - return frontController.service(httpRequest); + HttpRequest request = HttpRequest.from(bufferedReader); + frontController.service(request, response); } catch (HttpException e) { - return httpExceptionHandler.handleException(e); + httpExceptionHandler.handleException(e, response); + } catch (Exception e) { + httpExceptionHandler.setInternalServerError(response); } } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpExceptionHandler.java b/tomcat/src/main/java/org/apache/coyote/http11/HttpExceptionHandler.java index d470927256..84337ec0af 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/HttpExceptionHandler.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/HttpExceptionHandler.java @@ -1,6 +1,7 @@ package org.apache.coyote.http11; import static org.apache.coyote.http11.ContentType.TEXT_HTML; +import static org.apache.coyote.http11.HttpStatus.INTERNAL_SERVER_ERROR; import nextstep.jwp.common.ResourceLoader; @@ -8,14 +9,22 @@ public class HttpExceptionHandler { private static final String RESOURCE_PATH_FORMAT = "static/%s.html"; - public HttpResponse handleException(HttpException e) { + public void handleException(HttpException e, HttpResponse response) { HttpStatus httpStatus = e.httpStatus(); int code = httpStatus.statusCode(); ResourceLoader resourceLoader = new ResourceLoader(); String body = resourceLoader.load(String.format(RESOURCE_PATH_FORMAT, code)); - return HttpResponse.status(httpStatus) - .contentType(TEXT_HTML) - .body(body) - .build(); + response.setStatus(httpStatus); + response.setHeader("Content-Type", TEXT_HTML.value()); + response.setBody(body); + } + + public void setInternalServerError(HttpResponse response) { + int code = INTERNAL_SERVER_ERROR.statusCode(); + ResourceLoader resourceLoader = new ResourceLoader(); + String body = resourceLoader.load(String.format(RESOURCE_PATH_FORMAT, code)); + response.setStatus(INTERNAL_SERVER_ERROR); + response.setHeader("Content-Type", TEXT_HTML.value()); + response.setBody(body); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpResponse.java b/tomcat/src/main/java/org/apache/coyote/http11/HttpResponse.java index 3f2781b483..8f0ea1a59d 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/HttpResponse.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/HttpResponse.java @@ -20,83 +20,51 @@ public class HttpResponse { private static final String EQUAL = "="; private static final String SEPARATOR = "\r\n"; - private final byte[] bytes; + private final Map headers = new LinkedHashMap<>(); + private final HttpCookie httpCookie = HttpCookie.empty(); + private HttpStatus httpStatus; + private String body; - private HttpResponse(byte[] bytes) { - this.bytes = bytes; + public void setStatus(HttpStatus httpStatus) { + this.httpStatus = httpStatus; } - public static Builder status(HttpStatus httpStatus) { - return new Builder(httpStatus); + public void setHeader(String name, String value) { + headers.put(name, value); } - public byte[] getBytes() { - return bytes; + public void setContentType(ContentType contentType) { + headers.put(CONTENT_TYPE, contentType.value()); } - public static class Builder { - - private final HttpStatus httpStatus; - private final HttpCookie httpCookie; - private ContentType contentType; - private String redirectUri; - private String body; - - private Builder(HttpStatus httpStatus) { - this.httpStatus = httpStatus; - httpCookie = HttpCookie.empty(); - } - - public Builder contentType(ContentType contentType) { - this.contentType = contentType; - return this; - } - - public Builder redirectUri(String redirectUri) { - this.redirectUri = redirectUri; - return this; - } - - public Builder cookie(String name, String value) { - httpCookie.addCookie(name, value); - return this; - } + public void addCookie(String name, String value) { + httpCookie.addCookie(name, value); + } - public Builder body(String body) { - this.body = body; - return this; - } + public void sendRedirect(String redirectUri) { + headers.put(LOCATION, redirectUri); + } - public HttpResponse build() { - Map headers = new LinkedHashMap<>(); - if (contentType != null) { - headers.put(CONTENT_TYPE, contentType.value()); - } - if (redirectUri != null) { - headers.put(LOCATION, redirectUri); - } - if (body != null) { - headers.put(CONTENT_LENGTH, String.valueOf(body.getBytes().length)); - } - return new HttpResponse(getBytes(headers)); - } + public void setBody(String body) { + this.body = body; + headers.put(CONTENT_LENGTH, String.valueOf(body.getBytes().length)); + } - private byte[] getBytes(Map headers) { - List response = new ArrayList<>(); - response.add(HTTP_VERSION + BLANK + httpStatus.statusCode() + BLANK + httpStatus + BLANK); - response.add(stringify(headers)); - httpCookie.getCookie(JSESSIONID) - .ifPresent(id -> response.add(SET_COOKIE + COLON + JSESSIONID + EQUAL + id + BLANK)); - response.add(EMPTY); - response.add(body); - return String.join(SEPARATOR, response).getBytes(); - } + public byte[] getBytes() { + List response = new ArrayList<>(); + response.add(HTTP_VERSION + BLANK + httpStatus.statusCode() + BLANK + httpStatus + BLANK); + response.add(stringify(headers)); + httpCookie.getCookie(JSESSIONID) + .ifPresent(id -> response.add(SET_COOKIE + COLON + JSESSIONID + EQUAL + id + BLANK)); + response.add(EMPTY); + response.add(body); + return String.join(SEPARATOR, response).getBytes(); + } - private String stringify(Map headers) { - List formattedHeaders = headers.keySet().stream() - .map(key -> key + COLON + headers.get(key) + BLANK) - .collect(Collectors.toList()); - return String.join(SEPARATOR, formattedHeaders); - } + private String stringify(Map headers) { + List formattedHeaders = headers.keySet().stream() + .map(key -> key + COLON + headers.get(key) + BLANK) + .collect(Collectors.toList()); + return String.join(SEPARATOR, formattedHeaders); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpStatus.java b/tomcat/src/main/java/org/apache/coyote/http11/HttpStatus.java index 7d41c00a68..9a6e7c5429 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/HttpStatus.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/HttpStatus.java @@ -6,6 +6,7 @@ public enum HttpStatus { FOUND(302), UNAUTHORIZED(401), BAD_REQUEST(404), + INTERNAL_SERVER_ERROR(500), ; private final int statusCode; From 923d82ddfd1d1cc4fb7ed57e84bf8ee05daab5ec Mon Sep 17 00:00:00 2001 From: odo27 Date: Wed, 13 Sep 2023 15:50:48 +0900 Subject: [PATCH 06/10] =?UTF-8?q?refactor:=20ResourceLoader=20load=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20static=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/nextstep/jwp/common/ResourceLoader.java | 4 ++-- .../java/nextstep/jwp/config/ControllerConfig.java | 14 ++++---------- .../presentation/ExceptionControllerAdvice.java | 3 +-- .../nextstep/jwp/presentation/LoginController.java | 6 ++---- .../jwp/presentation/RegisterController.java | 8 +------- .../jwp/presentation/ResourceController.java | 10 ++-------- .../apache/coyote/http11/HttpExceptionHandler.java | 6 ++---- 7 files changed, 14 insertions(+), 37 deletions(-) diff --git a/tomcat/src/main/java/nextstep/jwp/common/ResourceLoader.java b/tomcat/src/main/java/nextstep/jwp/common/ResourceLoader.java index 301c1249d6..d95255afa9 100644 --- a/tomcat/src/main/java/nextstep/jwp/common/ResourceLoader.java +++ b/tomcat/src/main/java/nextstep/jwp/common/ResourceLoader.java @@ -10,8 +10,8 @@ public class ResourceLoader { - public String load(String path) { - URL resource = getClass().getClassLoader().getResource(path); + public static String load(String path) { + URL resource = ResourceLoader.class.getClassLoader().getResource(path); if (resource == null) { throw new ResourceException(RESOURCE_NOT_FOUND); } diff --git a/tomcat/src/main/java/nextstep/jwp/config/ControllerConfig.java b/tomcat/src/main/java/nextstep/jwp/config/ControllerConfig.java index 357f4ff4f7..d33d4ded5f 100644 --- a/tomcat/src/main/java/nextstep/jwp/config/ControllerConfig.java +++ b/tomcat/src/main/java/nextstep/jwp/config/ControllerConfig.java @@ -1,6 +1,5 @@ package nextstep.jwp.config; -import nextstep.jwp.common.ResourceLoader; import nextstep.jwp.presentation.ExceptionControllerAdvice; import nextstep.jwp.presentation.FrontController; import nextstep.jwp.presentation.HomeController; @@ -14,18 +13,13 @@ public class ControllerConfig { public static final ExceptionControllerAdvice exceptionControllerAdvice = new ExceptionControllerAdvice(); - private static final ResourceLoader resourceLoader = new ResourceLoader(); private static final SessionManager sessionManager = new SessionManager(); private static final LoginService loginService = new LoginService(sessionManager); - private static final LoginController loginController = new LoginController(resourceLoader, loginService); - private static final HomeController homeController = new HomeController(); - private static final RegisterController registerController = new RegisterController(resourceLoader); - private static final ResourceController resourceController = new ResourceController(resourceLoader); private static final RequestMapping requestMapping = new RequestMapping( - homeController, - loginController, - registerController, - resourceController + new HomeController(), + new LoginController(loginService), + new RegisterController(), + new ResourceController() ); public static final FrontController frontController = new FrontController( requestMapping, diff --git a/tomcat/src/main/java/nextstep/jwp/presentation/ExceptionControllerAdvice.java b/tomcat/src/main/java/nextstep/jwp/presentation/ExceptionControllerAdvice.java index 6fa8b68f4e..eea72070f9 100644 --- a/tomcat/src/main/java/nextstep/jwp/presentation/ExceptionControllerAdvice.java +++ b/tomcat/src/main/java/nextstep/jwp/presentation/ExceptionControllerAdvice.java @@ -15,8 +15,7 @@ void handleException(BaseException e, HttpResponse response) { HttpStatus httpStatus = e.exceptionType().httpStatus(); response.setStatus(httpStatus); int code = httpStatus.statusCode(); - ResourceLoader resourceLoader = new ResourceLoader(); - String body = resourceLoader.load(String.format(RESOURCE_PATH_FORMAT, code)); + String body = ResourceLoader.load(String.format(RESOURCE_PATH_FORMAT, code)); response.setBody(body); response.setHeader("Content-Type", TEXT_HTML.value()); } diff --git a/tomcat/src/main/java/nextstep/jwp/presentation/LoginController.java b/tomcat/src/main/java/nextstep/jwp/presentation/LoginController.java index 4aef916b64..9c147cd8f5 100644 --- a/tomcat/src/main/java/nextstep/jwp/presentation/LoginController.java +++ b/tomcat/src/main/java/nextstep/jwp/presentation/LoginController.java @@ -13,11 +13,9 @@ public class LoginController extends AbstractController { private static final String JSESSIONID = "JSESSIONID"; - private final ResourceLoader resourceLoader; private final LoginService loginService; - public LoginController(ResourceLoader resourceLoader, LoginService loginService) { - this.resourceLoader = resourceLoader; + public LoginController(LoginService loginService) { this.loginService = loginService; } @@ -40,6 +38,6 @@ protected void doGet(HttpRequest request, HttpResponse response) { } response.setStatus(OK); response.setContentType(TEXT_HTML); - response.setBody(resourceLoader.load("static/login.html")); + response.setBody(ResourceLoader.load("static/login.html")); } } diff --git a/tomcat/src/main/java/nextstep/jwp/presentation/RegisterController.java b/tomcat/src/main/java/nextstep/jwp/presentation/RegisterController.java index c006c13eee..ded5551762 100644 --- a/tomcat/src/main/java/nextstep/jwp/presentation/RegisterController.java +++ b/tomcat/src/main/java/nextstep/jwp/presentation/RegisterController.java @@ -17,12 +17,6 @@ public class RegisterController extends AbstractController { private static final String INDEX_HTML = "/index.html"; - private final ResourceLoader resourceLoader; - - public RegisterController(ResourceLoader resourceLoader) { - this.resourceLoader = resourceLoader; - } - @Override protected void doPost(HttpRequest request, HttpResponse response) { register(request, response); @@ -31,7 +25,7 @@ protected void doPost(HttpRequest request, HttpResponse response) { @Override protected void doGet(HttpRequest request, HttpResponse response) { response.setStatus(OK); - response.setBody(resourceLoader.load("static/register.html")); + response.setBody(ResourceLoader.load("static/register.html")); response.setContentType(TEXT_HTML); } diff --git a/tomcat/src/main/java/nextstep/jwp/presentation/ResourceController.java b/tomcat/src/main/java/nextstep/jwp/presentation/ResourceController.java index 014b2516b0..07a9ab5ee9 100644 --- a/tomcat/src/main/java/nextstep/jwp/presentation/ResourceController.java +++ b/tomcat/src/main/java/nextstep/jwp/presentation/ResourceController.java @@ -11,22 +11,16 @@ public class ResourceController extends AbstractController { - private final ResourceLoader resourceLoader; - - public ResourceController(ResourceLoader resourceLoader) { - this.resourceLoader = resourceLoader; - } - @Override protected void doGet(HttpRequest request, HttpResponse response) { response.setStatus(OK); Optional acceptHeader = request.getHeader("Accept"); if (acceptHeader.isPresent() && acceptHeader.get().contains("text/css")) { response.setContentType(TEXT_CSS); - response.setBody(resourceLoader.load("static" + request.uri())); + response.setBody(ResourceLoader.load("static" + request.uri())); return; } response.setContentType(TEXT_HTML); - response.setBody(resourceLoader.load("static" + request.uri())); + response.setBody(ResourceLoader.load("static" + request.uri())); } } diff --git a/tomcat/src/main/java/org/apache/coyote/http11/HttpExceptionHandler.java b/tomcat/src/main/java/org/apache/coyote/http11/HttpExceptionHandler.java index 84337ec0af..c6abf1b4e7 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/HttpExceptionHandler.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/HttpExceptionHandler.java @@ -12,8 +12,7 @@ public class HttpExceptionHandler { public void handleException(HttpException e, HttpResponse response) { HttpStatus httpStatus = e.httpStatus(); int code = httpStatus.statusCode(); - ResourceLoader resourceLoader = new ResourceLoader(); - String body = resourceLoader.load(String.format(RESOURCE_PATH_FORMAT, code)); + String body = ResourceLoader.load(String.format(RESOURCE_PATH_FORMAT, code)); response.setStatus(httpStatus); response.setHeader("Content-Type", TEXT_HTML.value()); response.setBody(body); @@ -21,8 +20,7 @@ public void handleException(HttpException e, HttpResponse response) { public void setInternalServerError(HttpResponse response) { int code = INTERNAL_SERVER_ERROR.statusCode(); - ResourceLoader resourceLoader = new ResourceLoader(); - String body = resourceLoader.load(String.format(RESOURCE_PATH_FORMAT, code)); + String body = ResourceLoader.load(String.format(RESOURCE_PATH_FORMAT, code)); response.setStatus(INTERNAL_SERVER_ERROR); response.setHeader("Content-Type", TEXT_HTML.value()); response.setBody(body); From 1e76da644799b90e55600acd43808ff99021186a Mon Sep 17 00:00:00 2001 From: odo27 Date: Wed, 13 Sep 2023 16:01:18 +0900 Subject: [PATCH 07/10] =?UTF-8?q?refactor:=20SessionManager=20add,=20findS?= =?UTF-8?q?ession=20=EB=A9=94=EC=84=9C=EB=93=9C=20static=20=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/nextstep/jwp/config/ControllerConfig.java | 5 +---- .../main/java/nextstep/jwp/service/LoginService.java | 10 ++-------- .../main/java/org/apache/catalina/SessionManager.java | 8 ++------ 3 files changed, 5 insertions(+), 18 deletions(-) diff --git a/tomcat/src/main/java/nextstep/jwp/config/ControllerConfig.java b/tomcat/src/main/java/nextstep/jwp/config/ControllerConfig.java index d33d4ded5f..9b18c787d5 100644 --- a/tomcat/src/main/java/nextstep/jwp/config/ControllerConfig.java +++ b/tomcat/src/main/java/nextstep/jwp/config/ControllerConfig.java @@ -8,16 +8,13 @@ import nextstep.jwp.presentation.RequestMapping; import nextstep.jwp.presentation.ResourceController; import nextstep.jwp.service.LoginService; -import org.apache.catalina.SessionManager; public class ControllerConfig { public static final ExceptionControllerAdvice exceptionControllerAdvice = new ExceptionControllerAdvice(); - private static final SessionManager sessionManager = new SessionManager(); - private static final LoginService loginService = new LoginService(sessionManager); private static final RequestMapping requestMapping = new RequestMapping( new HomeController(), - new LoginController(loginService), + new LoginController(new LoginService()), new RegisterController(), new ResourceController() ); diff --git a/tomcat/src/main/java/nextstep/jwp/service/LoginService.java b/tomcat/src/main/java/nextstep/jwp/service/LoginService.java index 5bd249b743..b71ab1270d 100644 --- a/tomcat/src/main/java/nextstep/jwp/service/LoginService.java +++ b/tomcat/src/main/java/nextstep/jwp/service/LoginService.java @@ -21,14 +21,8 @@ public class LoginService { private static final String JSESSIONID = "JSESSIONID"; private static final String INDEX_HTML = "/index.html"; - private final SessionManager sessionManager; - - public LoginService(SessionManager sessionManager) { - this.sessionManager = sessionManager; - } - public void loginWithSession(String jsessionid, HttpResponse response) { - Session session = sessionManager.findSession(jsessionid) + Session session = SessionManager.findSession(jsessionid) .orElseThrow(() -> new AuthException(INVALID_SESSION_ID)); if (session.getAttribute("user").isEmpty()) { throw new AuthException(USER_NO_EXIST_IN_SESSION); @@ -46,7 +40,7 @@ public void login(HttpRequest httpRequest, HttpResponse response) { String jsessionid = UUID.randomUUID().toString(); Session session = new Session(jsessionid); session.setAttribute("user", user.get()); - sessionManager.add(session); + SessionManager.add(session); response.setStatus(FOUND); response.sendRedirect(INDEX_HTML); response.addCookie(JSESSIONID, jsessionid); diff --git a/tomcat/src/main/java/org/apache/catalina/SessionManager.java b/tomcat/src/main/java/org/apache/catalina/SessionManager.java index e975d4d7d9..19ae55f6b9 100644 --- a/tomcat/src/main/java/org/apache/catalina/SessionManager.java +++ b/tomcat/src/main/java/org/apache/catalina/SessionManager.java @@ -8,18 +8,14 @@ public class SessionManager { private static final Map SESSIONS = new ConcurrentHashMap<>(); - public void add(Session session) { + public static void add(Session session) { SESSIONS.put(session.getId(), session); } - public Optional findSession(String id) { + public static Optional findSession(String id) { if (SESSIONS.containsKey(id)) { return Optional.of(SESSIONS.get(id)); } return Optional.empty(); } - - public void remove(Session session) { - SESSIONS.remove(session.getId()); - } } From dd3c1401aa25e730b546235bc0a32b49141a8b28 Mon Sep 17 00:00:00 2001 From: odo27 Date: Wed, 13 Sep 2023 16:04:43 +0900 Subject: [PATCH 08/10] =?UTF-8?q?refactor:=20login=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/nextstep/jwp/presentation/LoginController.java | 6 +++++- .../src/main/java/nextstep/jwp/service/LoginService.java | 7 +------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/tomcat/src/main/java/nextstep/jwp/presentation/LoginController.java b/tomcat/src/main/java/nextstep/jwp/presentation/LoginController.java index 9c147cd8f5..67b9781882 100644 --- a/tomcat/src/main/java/nextstep/jwp/presentation/LoginController.java +++ b/tomcat/src/main/java/nextstep/jwp/presentation/LoginController.java @@ -4,6 +4,7 @@ import static org.apache.coyote.http11.HttpStatus.OK; import java.util.Optional; +import nextstep.jwp.common.FormData; import nextstep.jwp.common.ResourceLoader; import nextstep.jwp.service.LoginService; import org.apache.coyote.http11.HttpRequest; @@ -26,7 +27,10 @@ protected void doPost(HttpRequest request, HttpResponse response) { loginService.loginWithSession(jsessionid.get(), response); return; } - loginService.login(request, response); + FormData formData = FormData.from(request.getBody()); + String account = formData.get("account"); + String password = formData.get("password"); + loginService.login(account, password, response); } @Override diff --git a/tomcat/src/main/java/nextstep/jwp/service/LoginService.java b/tomcat/src/main/java/nextstep/jwp/service/LoginService.java index b71ab1270d..e045816684 100644 --- a/tomcat/src/main/java/nextstep/jwp/service/LoginService.java +++ b/tomcat/src/main/java/nextstep/jwp/service/LoginService.java @@ -7,13 +7,11 @@ import java.util.Optional; import java.util.UUID; -import nextstep.jwp.common.FormData; import nextstep.jwp.db.InMemoryUserRepository; import nextstep.jwp.exception.AuthException; import nextstep.jwp.model.User; import org.apache.catalina.Session; import org.apache.catalina.SessionManager; -import org.apache.coyote.http11.HttpRequest; import org.apache.coyote.http11.HttpResponse; public class LoginService { @@ -31,10 +29,7 @@ public void loginWithSession(String jsessionid, HttpResponse response) { response.sendRedirect(INDEX_HTML); } - public void login(HttpRequest httpRequest, HttpResponse response) { - FormData formData = FormData.from(httpRequest.getBody()); - String account = formData.get("account"); - String password = formData.get("password"); + public void login(String account, String password, HttpResponse response) { Optional user = InMemoryUserRepository.findByAccount(account); if (user.isPresent() && user.get().checkPassword(password)) { String jsessionid = UUID.randomUUID().toString(); From 2d836943648e72d41d669fd685953b1b0f84a096 Mon Sep 17 00:00:00 2001 From: odo27 Date: Wed, 13 Sep 2023 16:12:18 +0900 Subject: [PATCH 09/10] =?UTF-8?q?refactor:=20process=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=8B=9C=EA=B7=B8=EB=8B=88=EC=B2=98=20=EA=B0=80?= =?UTF-8?q?=EB=8F=85=EC=84=B1=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/apache/coyote/http11/Http11Processor.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java index 53374f6f04..2e46cc27c6 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java @@ -38,8 +38,10 @@ public void process(final Socket connection) { InputStreamReader inputStreamReader = new InputStreamReader(inputStream); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); + HttpRequest request = HttpRequest.from(bufferedReader); HttpResponse response = new HttpResponse(); - process(bufferedReader, response); + process(request, response); + outputStream.write(response.getBytes()); outputStream.flush(); } catch (IOException | UncheckedServletException e) { @@ -47,10 +49,9 @@ public void process(final Socket connection) { } } - private void process(BufferedReader bufferedReader, HttpResponse response) { + private void process(HttpRequest request, HttpResponse response) { HttpExceptionHandler httpExceptionHandler = new HttpExceptionHandler(); try { - HttpRequest request = HttpRequest.from(bufferedReader); frontController.service(request, response); } catch (HttpException e) { httpExceptionHandler.handleException(e, response); From d06d4fe97633e31f84dde7832ef6e2b2b153d6e0 Mon Sep 17 00:00:00 2001 From: odo27 Date: Wed, 13 Sep 2023 16:23:29 +0900 Subject: [PATCH 10/10] =?UTF-8?q?refactor:=20=ED=8F=BC=20=EC=96=91?= =?UTF-8?q?=EC=8B=9D=EC=9D=B4=20=EC=9C=A0=ED=9A=A8=ED=95=98=EC=A7=80=20?= =?UTF-8?q?=EC=95=8A=EC=9D=84=20=EB=95=8C=20=EC=98=88=EC=99=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/nextstep/jwp/common/FormData.java | 6 ++-- .../jwp/exception/AuthExceptionType.java | 1 - .../jwp/exception/FormDataException.java | 15 ++++++++++ .../jwp/exception/FormDataExceptionType.java | 29 +++++++++++++++++++ 4 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 tomcat/src/main/java/nextstep/jwp/exception/FormDataException.java create mode 100644 tomcat/src/main/java/nextstep/jwp/exception/FormDataExceptionType.java diff --git a/tomcat/src/main/java/nextstep/jwp/common/FormData.java b/tomcat/src/main/java/nextstep/jwp/common/FormData.java index 802a2e8e5d..d024f81d22 100644 --- a/tomcat/src/main/java/nextstep/jwp/common/FormData.java +++ b/tomcat/src/main/java/nextstep/jwp/common/FormData.java @@ -1,10 +1,10 @@ package nextstep.jwp.common; -import static nextstep.jwp.exception.AuthExceptionType.INVALID_FORM; +import static nextstep.jwp.exception.FormDataExceptionType.INVALID_FORM; import java.util.HashMap; import java.util.Map; -import nextstep.jwp.exception.AuthException; +import nextstep.jwp.exception.FormDataException; public class FormData { @@ -33,6 +33,6 @@ public String get(String key) { if (formTable.containsKey(key)) { return formTable.get(key); } - throw new AuthException(INVALID_FORM); + throw new FormDataException(INVALID_FORM); } } diff --git a/tomcat/src/main/java/nextstep/jwp/exception/AuthExceptionType.java b/tomcat/src/main/java/nextstep/jwp/exception/AuthExceptionType.java index 3a9a57afc0..fc5045ba8b 100644 --- a/tomcat/src/main/java/nextstep/jwp/exception/AuthExceptionType.java +++ b/tomcat/src/main/java/nextstep/jwp/exception/AuthExceptionType.java @@ -11,7 +11,6 @@ public enum AuthExceptionType implements BaseExceptionType { USER_NO_EXIST_IN_SESSION(UNAUTHORIZED, "세션에 회원정보가 존재하지 않습니다"), INVALID_ID_OR_PASSWORD(UNAUTHORIZED, "아이디나 비밀번호를 확인해주세요"), DUPLICATED_ID(BAD_REQUEST, "이미 존재하는 아이디입니다. 다른 아이디로 가입해주세요"), - INVALID_FORM(BAD_REQUEST, "데이터가 존재하지 않습니다"), ; private final HttpStatus httpStatus; diff --git a/tomcat/src/main/java/nextstep/jwp/exception/FormDataException.java b/tomcat/src/main/java/nextstep/jwp/exception/FormDataException.java new file mode 100644 index 0000000000..3cef6e9224 --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/exception/FormDataException.java @@ -0,0 +1,15 @@ +package nextstep.jwp.exception; + +public class FormDataException extends BaseException { + + private final FormDataExceptionType exceptionType; + + public FormDataException(FormDataExceptionType exceptionType) { + this.exceptionType = exceptionType; + } + + @Override + public BaseExceptionType exceptionType() { + return exceptionType; + } +} diff --git a/tomcat/src/main/java/nextstep/jwp/exception/FormDataExceptionType.java b/tomcat/src/main/java/nextstep/jwp/exception/FormDataExceptionType.java new file mode 100644 index 0000000000..7112430280 --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/exception/FormDataExceptionType.java @@ -0,0 +1,29 @@ +package nextstep.jwp.exception; + +import static org.apache.coyote.http11.HttpStatus.BAD_REQUEST; + +import org.apache.coyote.http11.HttpStatus; + +public enum FormDataExceptionType implements BaseExceptionType { + + INVALID_FORM(BAD_REQUEST, "데이터가 존재하지 않습니다"), + ; + + private final HttpStatus httpStatus; + private final String errorMessage; + + FormDataExceptionType(HttpStatus httpStatus, String errorMessage) { + this.httpStatus = httpStatus; + this.errorMessage = errorMessage; + } + + @Override + public HttpStatus httpStatus() { + return httpStatus; + } + + @Override + public String errorMessage() { + return errorMessage; + } +}