diff --git a/tomcat/src/main/java/nextstep/jwp/controller/AbstractController.java b/tomcat/src/main/java/nextstep/jwp/controller/AbstractController.java new file mode 100644 index 0000000000..f548ea69da --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/controller/AbstractController.java @@ -0,0 +1,27 @@ +package nextstep.jwp.controller; + +import nextstep.jwp.handle.ViewResolver; +import org.apache.coyote.common.HttpMethod; +import org.apache.coyote.common.HttpStatus; +import org.apache.coyote.request.HttpRequest; +import org.apache.coyote.response.HttpResponse; + +public abstract class AbstractController implements Controller { + + @Override + public void service(final HttpRequest request, final HttpResponse response) throws Exception { + if (request.getHttpMethod() == HttpMethod.GET) { + doGet(request, response); + return; + } + if (request.getHttpMethod() == HttpMethod.POST) { + doPost(request, response); + return; + } + ViewResolver.renderPage(response, HttpStatus.NOT_FOUND, "404.html"); + } + + protected abstract void doPost(final HttpRequest request, final HttpResponse response) throws Exception; + + protected abstract void doGet(final HttpRequest request, final HttpResponse response) throws Exception; +} diff --git a/tomcat/src/main/java/nextstep/jwp/exception/HandlerMappingException.java b/tomcat/src/main/java/nextstep/jwp/exception/HandlerMappingException.java new file mode 100644 index 0000000000..357e6c6149 --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/exception/HandlerMappingException.java @@ -0,0 +1,8 @@ +package nextstep.jwp.exception; + +public class HandlerMappingException extends RuntimeException { + + public HandlerMappingException() { + super("Handler Mapping Fail"); + } +} diff --git a/tomcat/src/main/java/nextstep/jwp/servlet/DispatcherServlet.java b/tomcat/src/main/java/nextstep/jwp/servlet/DispatcherServlet.java new file mode 100644 index 0000000000..8d75a28a75 --- /dev/null +++ b/tomcat/src/main/java/nextstep/jwp/servlet/DispatcherServlet.java @@ -0,0 +1,78 @@ +package nextstep.jwp.servlet; + +import nextstep.jwp.controller.FileController; +import nextstep.jwp.controller.HelloWorldController; +import nextstep.jwp.controller.LoginController; +import nextstep.jwp.controller.RegisterController; +import nextstep.jwp.exception.HandlerMappingException; +import nextstep.jwp.handle.HandlerMapping; +import nextstep.jwp.handle.HandlerMethod; +import nextstep.jwp.handle.mapping.GetFileMappingInfo; +import nextstep.jwp.handle.mapping.GetHelloWorldMappingInfo; +import nextstep.jwp.handle.mapping.GetLoginMappingInfo; +import nextstep.jwp.handle.mapping.GetRegisterMappingInfo; +import nextstep.jwp.handle.mapping.PostLoginMappingInfo; +import nextstep.jwp.handle.mapping.PostRegisterMappingInfo; +import org.apache.catalina.core.Servlet; +import org.apache.coyote.request.HttpRequest; +import org.apache.coyote.response.HttpResponse; + +public class DispatcherServlet implements Servlet { + + private HandlerMapping handlerMapping; + + public DispatcherServlet() { + try { + this.handlerMapping = new HandlerMapping(); + handlerMapping.addMappingInfo( + new GetFileMappingInfo(), + new HandlerMethod( + FileController.getInstance(), + FileController.class.getDeclaredMethod("doGet", HttpRequest.class, HttpResponse.class) + ) + ); + handlerMapping.addMappingInfo( + new GetHelloWorldMappingInfo(), + new HandlerMethod( + HelloWorldController.getInstance(), + HelloWorldController.class.getDeclaredMethod("doGet", HttpRequest.class, HttpResponse.class) + ) + ); + handlerMapping.addMappingInfo( + new GetLoginMappingInfo(), + new HandlerMethod( + LoginController.getInstance(), + LoginController.class.getDeclaredMethod("doGet", HttpRequest.class, HttpResponse.class) + ) + ); + handlerMapping.addMappingInfo( + new PostLoginMappingInfo(), + new HandlerMethod( + LoginController.getInstance(), + LoginController.class.getDeclaredMethod("doPost", HttpRequest.class, HttpResponse.class) + ) + ); + handlerMapping.addMappingInfo( + new GetRegisterMappingInfo(), + new HandlerMethod( + RegisterController.getInstance(), + RegisterController.class.getDeclaredMethod("doGet", HttpRequest.class, HttpResponse.class) + )); + handlerMapping.addMappingInfo( + new PostRegisterMappingInfo(), + new HandlerMethod( + RegisterController.getInstance(), + RegisterController.class.getDeclaredMethod("doPost", HttpRequest.class, HttpResponse.class) + ) + ); + } catch (NoSuchMethodException e) { + throw new HandlerMappingException(); + } + } + + @Override + public void service(final HttpRequest request, final HttpResponse response) throws Exception { + final HandlerMethod handlerMethod = handlerMapping.getHandlerMethod(request); + handlerMethod.invokeMethod(request, response); + } +} diff --git a/tomcat/src/main/java/org/apache/catalina/core/ContextManager.java b/tomcat/src/main/java/org/apache/catalina/core/ContextManager.java new file mode 100644 index 0000000000..63a18957e1 --- /dev/null +++ b/tomcat/src/main/java/org/apache/catalina/core/ContextManager.java @@ -0,0 +1,24 @@ +package org.apache.catalina.core; + +import java.util.ArrayList; +import java.util.List; +import nextstep.jwp.servlet.DispatcherServlet; +import org.apache.coyote.exception.NotFoundServletException; +import org.apache.coyote.request.HttpRequest; +import org.apache.coyote.response.HttpResponse; + +public class ContextManager { + + private static final List servlets = new ArrayList<>(); + + static { + servlets.add(new DispatcherServlet()); + } + + public static void invoke(final HttpRequest request, final HttpResponse response) throws Exception { + final Servlet servlet = servlets.stream() + .findFirst() + .orElseThrow(NotFoundServletException::new); + servlet.service(request, response); + } +} diff --git a/tomcat/src/main/java/org/apache/catalina/core/Servlet.java b/tomcat/src/main/java/org/apache/catalina/core/Servlet.java new file mode 100644 index 0000000000..e399d003ee --- /dev/null +++ b/tomcat/src/main/java/org/apache/catalina/core/Servlet.java @@ -0,0 +1,9 @@ +package org.apache.catalina.core; + +import org.apache.coyote.request.HttpRequest; +import org.apache.coyote.response.HttpResponse; + +public interface Servlet { + + void service(final HttpRequest request, final HttpResponse response) throws Exception; +} diff --git a/tomcat/src/main/java/org/apache/coyote/exception/NotFoundServletException.java b/tomcat/src/main/java/org/apache/coyote/exception/NotFoundServletException.java new file mode 100644 index 0000000000..63a17e5532 --- /dev/null +++ b/tomcat/src/main/java/org/apache/coyote/exception/NotFoundServletException.java @@ -0,0 +1,8 @@ +package org.apache.coyote.exception; + +public class NotFoundServletException extends RuntimeException { + + public NotFoundServletException() { + super("Match Servlet Not Found"); + } +} 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 1b87a792fb..7a4ca3457f 100644 --- a/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java +++ b/tomcat/src/main/java/org/apache/coyote/http11/Http11Processor.java @@ -3,9 +3,8 @@ import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.Socket; +import org.apache.catalina.core.ContextManager; import org.apache.coyote.Processor; -import org.apache.coyote.handle.HandlerMapping; -import org.apache.coyote.handle.HandlerMethod; import org.apache.coyote.request.HttpRequest; import org.apache.coyote.response.HttpResponse; import org.slf4j.Logger; @@ -33,12 +32,11 @@ public void process(final Socket connection) { final var outputStream = connection.getOutputStream(); final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)) ) { - final HttpRequest httpRequest = HttpRequest.parse(bufferedReader); - final HttpResponse httpResponse = new HttpResponse(httpRequest.getHttpVersion()); - final HandlerMethod handlerMethod = HandlerMapping.getHandlerMethod(httpRequest); - handlerMethod.invokeMethod(httpRequest, httpResponse); + final HttpRequest request = HttpRequest.parse(bufferedReader); + final HttpResponse response = new HttpResponse(request.getHttpVersion()); + ContextManager.invoke(request, response); - outputStream.write(httpResponse.toString().getBytes()); + outputStream.write(response.toString().getBytes()); outputStream.flush(); } catch (Exception e) { log.error(e.getMessage(), e);