From 2c3c46f7cdd7125d88eb4e3081ae311daac6a77e Mon Sep 17 00:00:00 2001 From: devHudi Date: Mon, 26 Sep 2022 15:43:56 +0900 Subject: [PATCH 1/8] =?UTF-8?q?refactor:=20ControllerScanner=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=EB=A5=BC=20=EC=B6=94=EA=B0=80=ED=95=98?= =?UTF-8?q?=EC=97=AC=20AnnotationHandlerMapping=EC=9D=98=20extractClasses(?= =?UTF-8?q?)=20=EB=A9=94=EC=86=8C=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tobe/AnnotationHandlerMapping.java | 18 +++-------- .../controller/tobe/ControllerScanner.java | 32 +++++++++++++++++++ 2 files changed, 37 insertions(+), 13 deletions(-) create mode 100644 mvc/src/main/java/nextstep/mvc/controller/tobe/ControllerScanner.java diff --git a/mvc/src/main/java/nextstep/mvc/controller/tobe/AnnotationHandlerMapping.java b/mvc/src/main/java/nextstep/mvc/controller/tobe/AnnotationHandlerMapping.java index ec9482ce4d..b5b57e9015 100644 --- a/mvc/src/main/java/nextstep/mvc/controller/tobe/AnnotationHandlerMapping.java +++ b/mvc/src/main/java/nextstep/mvc/controller/tobe/AnnotationHandlerMapping.java @@ -6,14 +6,10 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.stream.Collectors; import nextstep.mvc.HandlerMapping; import nextstep.mvc.controller.tobe.exception.ControllerNotFoundException; -import nextstep.web.annotation.Controller; import nextstep.web.annotation.RequestMapping; -import org.reflections.Reflections; -import org.reflections.scanners.Scanners; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,8 +26,9 @@ public AnnotationHandlerMapping(final Object... basePackage) { } public void initialize() { - Set> controllerClasses = extractClasses(); - List methods = extractMethods(controllerClasses); + ControllerScanner controllerScanner = new ControllerScanner(); + Map, Object> controllers = controllerScanner.getControllers(basePackage); + List methods = extractMethods(controllers); for (Method method : methods) { addHandlerExecutions(method); @@ -40,13 +37,8 @@ public void initialize() { log.info("Initialized AnnotationHandlerMapping!"); } - private Set> extractClasses() { - Reflections classReflections = new Reflections(basePackage, Scanners.TypesAnnotated); - return classReflections.getTypesAnnotatedWith(Controller.class); - } - - private List extractMethods(final Set> controllers) { - return controllers.stream() + private List extractMethods(final Map, Object> controllers) { + return controllers.keySet().stream() .flatMap(it -> Arrays.stream(it.getMethods())) .filter(it -> it.isAnnotationPresent(RequestMapping.class)) .collect(Collectors.toList()); diff --git a/mvc/src/main/java/nextstep/mvc/controller/tobe/ControllerScanner.java b/mvc/src/main/java/nextstep/mvc/controller/tobe/ControllerScanner.java new file mode 100644 index 0000000000..3e99fe9a73 --- /dev/null +++ b/mvc/src/main/java/nextstep/mvc/controller/tobe/ControllerScanner.java @@ -0,0 +1,32 @@ +package nextstep.mvc.controller.tobe; + +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import nextstep.web.annotation.Controller; +import org.reflections.Reflections; +import org.reflections.scanners.Scanners; + +public class ControllerScanner { + + public Map, Object> getControllers(final Object[] basePackage) { + Reflections classReflections = new Reflections(basePackage, Scanners.TypesAnnotated); + Set> classes = classReflections.getTypesAnnotatedWith(Controller.class); + + return instantiateControllers(classes); + } + + private Map, Object> instantiateControllers(final Set> classes) { + return classes.stream() + .collect(Collectors.toMap(clazz -> clazz, this::instantiateClass)); + } + + private Object instantiateClass(final Class clazz) { + try { + return clazz.getConstructor().newInstance(); + } catch (ReflectiveOperationException e) { + throw new IllegalArgumentException("Controller를 인스턴스화 할 수 없습니다."); + // TODO: 적절한 예외를 던져야함 + } + } +} From 16e9bc4a6ded997f2e820c7da121c25925b7f5df Mon Sep 17 00:00:00 2001 From: devHudi Date: Mon, 26 Sep 2022 16:24:48 +0900 Subject: [PATCH 2/8] =?UTF-8?q?refactor:=20ControllerHandlerAdapter,=20Han?= =?UTF-8?q?dlerExecutionHandlerAdapter=EC=99=80=20HandlerAdapterRegistry?= =?UTF-8?q?=EB=A5=BC=20=EA=B5=AC=ED=98=84=ED=95=98=EC=97=AC=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AppWebApplicationInitializer.java | 5 +++ .../java/nextstep/mvc/DispatcherServlet.java | 37 +++++-------------- .../controller/HandlerAdapterRegistry.java | 26 +++++++++++++ .../asis/ControllerHandlerAdapter.java | 23 ++++++++++++ .../tobe/HandlerExecutionHandlerAdapter.java | 20 ++++++++++ .../java/nextstep/mvc/view/ModelAndView.java | 7 ++++ 6 files changed, 91 insertions(+), 27 deletions(-) create mode 100644 mvc/src/main/java/nextstep/mvc/controller/HandlerAdapterRegistry.java create mode 100644 mvc/src/main/java/nextstep/mvc/controller/asis/ControllerHandlerAdapter.java create mode 100644 mvc/src/main/java/nextstep/mvc/controller/tobe/HandlerExecutionHandlerAdapter.java diff --git a/app/src/main/java/com/techcourse/AppWebApplicationInitializer.java b/app/src/main/java/com/techcourse/AppWebApplicationInitializer.java index 674d245cd8..5abff25665 100644 --- a/app/src/main/java/com/techcourse/AppWebApplicationInitializer.java +++ b/app/src/main/java/com/techcourse/AppWebApplicationInitializer.java @@ -2,7 +2,9 @@ import jakarta.servlet.ServletContext; import nextstep.mvc.DispatcherServlet; +import nextstep.mvc.controller.asis.ControllerHandlerAdapter; import nextstep.mvc.controller.tobe.AnnotationHandlerMapping; +import nextstep.mvc.controller.tobe.HandlerExecutionHandlerAdapter; import nextstep.web.WebApplicationInitializer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -14,6 +16,9 @@ public class AppWebApplicationInitializer implements WebApplicationInitializer { @Override public void onStartup(final ServletContext servletContext) { final var dispatcherServlet = new DispatcherServlet(); + dispatcherServlet.addHandlerAdapter(new ControllerHandlerAdapter()); + dispatcherServlet.addHandlerAdapter(new HandlerExecutionHandlerAdapter()); + dispatcherServlet.addHandlerMapping(new ManualHandlerMapping()); dispatcherServlet.addHandlerMapping(new AnnotationHandlerMapping("com.techcourse.controller")); diff --git a/mvc/src/main/java/nextstep/mvc/DispatcherServlet.java b/mvc/src/main/java/nextstep/mvc/DispatcherServlet.java index 5f531acde5..67eeb66d50 100644 --- a/mvc/src/main/java/nextstep/mvc/DispatcherServlet.java +++ b/mvc/src/main/java/nextstep/mvc/DispatcherServlet.java @@ -6,11 +6,8 @@ import jakarta.servlet.http.HttpServletResponse; import java.util.ArrayList; import java.util.List; -import java.util.Map; import java.util.Objects; -import nextstep.mvc.controller.asis.Controller; -import nextstep.mvc.controller.tobe.HandlerExecution; -import nextstep.mvc.view.JspView; +import nextstep.mvc.controller.HandlerAdapterRegistry; import nextstep.mvc.view.ModelAndView; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -20,9 +17,11 @@ public class DispatcherServlet extends HttpServlet { private static final long serialVersionUID = 1L; private static final Logger log = LoggerFactory.getLogger(DispatcherServlet.class); + private final HandlerAdapterRegistry handlerAdapterRegistry; private final List handlerMappings; public DispatcherServlet() { + this.handlerAdapterRegistry = new HandlerAdapterRegistry(); this.handlerMappings = new ArrayList<>(); } @@ -31,6 +30,10 @@ public void init() { handlerMappings.forEach(HandlerMapping::initialize); } + public void addHandlerAdapter(final HandlerAdapter handlerAdapter) { + handlerAdapterRegistry.addHandlerAdapter(handlerAdapter); + } + public void addHandlerMapping(final HandlerMapping handlerMapping) { handlerMappings.add(handlerMapping); } @@ -42,18 +45,9 @@ protected void service(final HttpServletRequest request, final HttpServletRespon try { final Object controller = getController(request); - - // TODO: 다형성을 통해 해결해야함 - if (controller instanceof HandlerExecution) { - HandlerExecution handlerExecution = (HandlerExecution) controller; - ModelAndView modelAndView = handlerExecution.handle(request, response); - Map model = modelAndView.getModel(); - modelAndView.getView().render(model, request, response); - return; - } - - final var viewName = ((Controller) controller).execute(request, response); - move(viewName, request, response); + HandlerAdapter handlerAdapter = handlerAdapterRegistry.getHandlerAdapter(controller); + ModelAndView modelAndView = handlerAdapter.handle(request, response, controller); + modelAndView.render(request, response); } catch (Throwable e) { log.error("Exception : {}", e.getMessage(), e); throw new ServletException(e.getMessage()); @@ -67,15 +61,4 @@ private Object getController(final HttpServletRequest request) { .findFirst() .orElseThrow(); } - - private void move(final String viewName, final HttpServletRequest request, final HttpServletResponse response) - throws Exception { - if (viewName.startsWith(JspView.REDIRECT_PREFIX)) { - response.sendRedirect(viewName.substring(JspView.REDIRECT_PREFIX.length())); - return; - } - - final var requestDispatcher = request.getRequestDispatcher(viewName); - requestDispatcher.forward(request, response); - } } diff --git a/mvc/src/main/java/nextstep/mvc/controller/HandlerAdapterRegistry.java b/mvc/src/main/java/nextstep/mvc/controller/HandlerAdapterRegistry.java new file mode 100644 index 0000000000..f5e0695086 --- /dev/null +++ b/mvc/src/main/java/nextstep/mvc/controller/HandlerAdapterRegistry.java @@ -0,0 +1,26 @@ +package nextstep.mvc.controller; + +import java.util.ArrayList; +import java.util.List; +import nextstep.mvc.HandlerAdapter; + +public class HandlerAdapterRegistry { + + private final List handlerAdapters; + + public HandlerAdapterRegistry() { + this.handlerAdapters = new ArrayList<>(); + } + + public void addHandlerAdapter(final HandlerAdapter handlerAdapter) { + handlerAdapters.add(handlerAdapter); + } + + public HandlerAdapter getHandlerAdapter(final Object handler) { + return handlerAdapters.stream() + .filter(it -> it.supports(handler)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("지원하지 않는 핸들러입니다.")); + // TODO: 적절한 예외로 변경 + } +} diff --git a/mvc/src/main/java/nextstep/mvc/controller/asis/ControllerHandlerAdapter.java b/mvc/src/main/java/nextstep/mvc/controller/asis/ControllerHandlerAdapter.java new file mode 100644 index 0000000000..d2e92f7d3e --- /dev/null +++ b/mvc/src/main/java/nextstep/mvc/controller/asis/ControllerHandlerAdapter.java @@ -0,0 +1,23 @@ +package nextstep.mvc.controller.asis; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import nextstep.mvc.HandlerAdapter; +import nextstep.mvc.view.JspView; +import nextstep.mvc.view.ModelAndView; + +public class ControllerHandlerAdapter implements HandlerAdapter { + + @Override + public boolean supports(final Object handler) { + return handler instanceof Controller; + } + + @Override + public ModelAndView handle(final HttpServletRequest request, final HttpServletResponse response, + final Object handler) throws Exception { + String viewName = ((Controller) handler).execute(request, response); + JspView jspView = new JspView(viewName); + return new ModelAndView(jspView); + } +} diff --git a/mvc/src/main/java/nextstep/mvc/controller/tobe/HandlerExecutionHandlerAdapter.java b/mvc/src/main/java/nextstep/mvc/controller/tobe/HandlerExecutionHandlerAdapter.java new file mode 100644 index 0000000000..4642dbcb20 --- /dev/null +++ b/mvc/src/main/java/nextstep/mvc/controller/tobe/HandlerExecutionHandlerAdapter.java @@ -0,0 +1,20 @@ +package nextstep.mvc.controller.tobe; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import nextstep.mvc.HandlerAdapter; +import nextstep.mvc.view.ModelAndView; + +public class HandlerExecutionHandlerAdapter implements HandlerAdapter { + + @Override + public boolean supports(final Object handler) { + return handler instanceof HandlerExecution; + } + + @Override + public ModelAndView handle(final HttpServletRequest request, final HttpServletResponse response, + final Object handler) throws Exception { + return ((HandlerExecution) handler).handle(request, response); + } +} diff --git a/mvc/src/main/java/nextstep/mvc/view/ModelAndView.java b/mvc/src/main/java/nextstep/mvc/view/ModelAndView.java index cb172084b3..6f3fea65ad 100644 --- a/mvc/src/main/java/nextstep/mvc/view/ModelAndView.java +++ b/mvc/src/main/java/nextstep/mvc/view/ModelAndView.java @@ -1,5 +1,7 @@ package nextstep.mvc.view; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -30,4 +32,9 @@ public Map getModel() { public View getView() { return view; } + + public void render(final HttpServletRequest httpServletRequest, final HttpServletResponse httpServletResponse) + throws Exception { + view.render(model, httpServletRequest, httpServletResponse); + } } From d779d20cc807ae3155fa1c2f476ddc11c8b7ab74 Mon Sep 17 00:00:00 2001 From: devHudi Date: Mon, 26 Sep 2022 16:28:45 +0900 Subject: [PATCH 3/8] =?UTF-8?q?refactor:=20RegisterController=EC=99=80=20R?= =?UTF-8?q?egisterViewController=EB=A5=BC=20=EC=96=B4=EB=85=B8=ED=85=8C?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=EA=B8=B0=EB=B0=98=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/techcourse/ManualHandlerMapping.java | 11 +++++----- .../controller/RegisterController.java | 22 ++++++++++++++----- .../controller/RegisterViewController.java | 13 ----------- .../java/nextstep/mvc/DispatcherServlet.java | 1 - .../HandlerAdapterRegistry.java | 3 +-- 5 files changed, 23 insertions(+), 27 deletions(-) delete mode 100644 app/src/main/java/com/techcourse/controller/RegisterViewController.java rename mvc/src/main/java/nextstep/mvc/{controller => }/HandlerAdapterRegistry.java (91%) diff --git a/app/src/main/java/com/techcourse/ManualHandlerMapping.java b/app/src/main/java/com/techcourse/ManualHandlerMapping.java index 8a6fa9080f..c6c603fb4a 100644 --- a/app/src/main/java/com/techcourse/ManualHandlerMapping.java +++ b/app/src/main/java/com/techcourse/ManualHandlerMapping.java @@ -1,16 +1,17 @@ package com.techcourse; -import com.techcourse.controller.*; +import com.techcourse.controller.LoginController; +import com.techcourse.controller.LoginViewController; +import com.techcourse.controller.LogoutController; import jakarta.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.Map; import nextstep.mvc.HandlerMapping; import nextstep.mvc.controller.asis.Controller; import nextstep.mvc.controller.asis.ForwardController; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.HashMap; -import java.util.Map; - public class ManualHandlerMapping implements HandlerMapping { private static final Logger log = LoggerFactory.getLogger(ManualHandlerMapping.class); @@ -23,8 +24,6 @@ public void initialize() { controllers.put("/login", new LoginController()); controllers.put("/login/view", new LoginViewController()); controllers.put("/logout", new LogoutController()); - controllers.put("/register/view", new RegisterViewController()); - controllers.put("/register", new RegisterController()); log.info("Initialized Handler Mapping!"); controllers.keySet() diff --git a/app/src/main/java/com/techcourse/controller/RegisterController.java b/app/src/main/java/com/techcourse/controller/RegisterController.java index 56bb436f6e..e97ef694b1 100644 --- a/app/src/main/java/com/techcourse/controller/RegisterController.java +++ b/app/src/main/java/com/techcourse/controller/RegisterController.java @@ -4,18 +4,30 @@ import com.techcourse.repository.InMemoryUserRepository; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import nextstep.mvc.controller.asis.Controller; +import nextstep.mvc.view.JspView; +import nextstep.mvc.view.ModelAndView; +import nextstep.web.annotation.Controller; +import nextstep.web.annotation.RequestMapping; +import nextstep.web.support.RequestMethod; -public class RegisterController implements Controller { +@Controller +public class RegisterController { - @Override - public String execute(final HttpServletRequest req, final HttpServletResponse res) throws Exception { + @RequestMapping(value = "/register", method = RequestMethod.POST) + public ModelAndView save(HttpServletRequest req, HttpServletResponse res) { final var user = new User(2, req.getParameter("account"), req.getParameter("password"), req.getParameter("email")); InMemoryUserRepository.save(user); - return "redirect:/index.jsp"; + JspView jspView = new JspView("redirect:/index.jsp"); + return new ModelAndView(jspView); + } + + @RequestMapping(value = "/register/view", method = RequestMethod.GET) + public ModelAndView show(HttpServletRequest req, HttpServletResponse res) { + JspView jspView = new JspView("/register.jsp"); + return new ModelAndView(jspView); } } diff --git a/app/src/main/java/com/techcourse/controller/RegisterViewController.java b/app/src/main/java/com/techcourse/controller/RegisterViewController.java deleted file mode 100644 index 052639134b..0000000000 --- a/app/src/main/java/com/techcourse/controller/RegisterViewController.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.techcourse.controller; - -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import nextstep.mvc.controller.asis.Controller; - -public class RegisterViewController implements Controller { - - @Override - public String execute(final HttpServletRequest req, final HttpServletResponse res) throws Exception { - return "/register.jsp"; - } -} diff --git a/mvc/src/main/java/nextstep/mvc/DispatcherServlet.java b/mvc/src/main/java/nextstep/mvc/DispatcherServlet.java index 67eeb66d50..c0cc5d20c7 100644 --- a/mvc/src/main/java/nextstep/mvc/DispatcherServlet.java +++ b/mvc/src/main/java/nextstep/mvc/DispatcherServlet.java @@ -7,7 +7,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; -import nextstep.mvc.controller.HandlerAdapterRegistry; import nextstep.mvc.view.ModelAndView; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/mvc/src/main/java/nextstep/mvc/controller/HandlerAdapterRegistry.java b/mvc/src/main/java/nextstep/mvc/HandlerAdapterRegistry.java similarity index 91% rename from mvc/src/main/java/nextstep/mvc/controller/HandlerAdapterRegistry.java rename to mvc/src/main/java/nextstep/mvc/HandlerAdapterRegistry.java index f5e0695086..7148eda8dd 100644 --- a/mvc/src/main/java/nextstep/mvc/controller/HandlerAdapterRegistry.java +++ b/mvc/src/main/java/nextstep/mvc/HandlerAdapterRegistry.java @@ -1,8 +1,7 @@ -package nextstep.mvc.controller; +package nextstep.mvc; import java.util.ArrayList; import java.util.List; -import nextstep.mvc.HandlerAdapter; public class HandlerAdapterRegistry { From ddcb8ed5b573c2235a7e5b5286838a319fffcefa Mon Sep 17 00:00:00 2001 From: devHudi Date: Mon, 26 Sep 2022 16:42:30 +0900 Subject: [PATCH 4/8] =?UTF-8?q?refactor:=20HandlerMappingRegistry=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/nextstep/mvc/DispatcherServlet.java | 23 +++++---------- .../nextstep/mvc/HandlerMappingRegistry.java | 28 +++++++++++++++++++ 2 files changed, 35 insertions(+), 16 deletions(-) create mode 100644 mvc/src/main/java/nextstep/mvc/HandlerMappingRegistry.java diff --git a/mvc/src/main/java/nextstep/mvc/DispatcherServlet.java b/mvc/src/main/java/nextstep/mvc/DispatcherServlet.java index c0cc5d20c7..1e70e5d889 100644 --- a/mvc/src/main/java/nextstep/mvc/DispatcherServlet.java +++ b/mvc/src/main/java/nextstep/mvc/DispatcherServlet.java @@ -4,9 +4,7 @@ import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; +import nextstep.mvc.controller.tobe.exception.ControllerNotFoundException; import nextstep.mvc.view.ModelAndView; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -17,16 +15,15 @@ public class DispatcherServlet extends HttpServlet { private static final Logger log = LoggerFactory.getLogger(DispatcherServlet.class); private final HandlerAdapterRegistry handlerAdapterRegistry; - private final List handlerMappings; + private final HandlerMappingRegistry handlerMappingRegistry; public DispatcherServlet() { this.handlerAdapterRegistry = new HandlerAdapterRegistry(); - this.handlerMappings = new ArrayList<>(); + this.handlerMappingRegistry = new HandlerMappingRegistry(); } @Override public void init() { - handlerMappings.forEach(HandlerMapping::initialize); } public void addHandlerAdapter(final HandlerAdapter handlerAdapter) { @@ -34,7 +31,7 @@ public void addHandlerAdapter(final HandlerAdapter handlerAdapter) { } public void addHandlerMapping(final HandlerMapping handlerMapping) { - handlerMappings.add(handlerMapping); + handlerMappingRegistry.addHandlerMapping(handlerMapping); } @Override @@ -43,7 +40,9 @@ protected void service(final HttpServletRequest request, final HttpServletRespon log.debug("Method : {}, Request URI : {}", request.getMethod(), request.getRequestURI()); try { - final Object controller = getController(request); + Object controller = handlerMappingRegistry.getHandler(request) + .orElseThrow(ControllerNotFoundException::new); + HandlerAdapter handlerAdapter = handlerAdapterRegistry.getHandlerAdapter(controller); ModelAndView modelAndView = handlerAdapter.handle(request, response, controller); modelAndView.render(request, response); @@ -52,12 +51,4 @@ protected void service(final HttpServletRequest request, final HttpServletRespon throw new ServletException(e.getMessage()); } } - - private Object getController(final HttpServletRequest request) { - return handlerMappings.stream() - .map(handlerMapping -> handlerMapping.getHandler(request)) - .filter(Objects::nonNull) - .findFirst() - .orElseThrow(); - } } diff --git a/mvc/src/main/java/nextstep/mvc/HandlerMappingRegistry.java b/mvc/src/main/java/nextstep/mvc/HandlerMappingRegistry.java new file mode 100644 index 0000000000..696543e2db --- /dev/null +++ b/mvc/src/main/java/nextstep/mvc/HandlerMappingRegistry.java @@ -0,0 +1,28 @@ +package nextstep.mvc; + +import jakarta.servlet.http.HttpServletRequest; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +public class HandlerMappingRegistry { + + private final List handlerMappings; + + public HandlerMappingRegistry() { + handlerMappings = new ArrayList<>(); + } + + public void addHandlerMapping(final HandlerMapping handlerMapping) { + handlerMapping.initialize(); + handlerMappings.add(handlerMapping); + } + + public Optional getHandler(final HttpServletRequest request) { + return handlerMappings.stream() + .map(handlerMapping -> handlerMapping.getHandler(request)) + .filter(Objects::nonNull) + .findFirst(); + } +} From 89d1e614bcac5fb7350f35cc9ae7b39b65975b4a Mon Sep 17 00:00:00 2001 From: devHudi Date: Mon, 26 Sep 2022 16:49:17 +0900 Subject: [PATCH 5/8] =?UTF-8?q?refactor:=20inline=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/nextstep/mvc/controller/tobe/HandlerKey.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/mvc/src/main/java/nextstep/mvc/controller/tobe/HandlerKey.java b/mvc/src/main/java/nextstep/mvc/controller/tobe/HandlerKey.java index 5decc74a23..882892cca3 100644 --- a/mvc/src/main/java/nextstep/mvc/controller/tobe/HandlerKey.java +++ b/mvc/src/main/java/nextstep/mvc/controller/tobe/HandlerKey.java @@ -20,11 +20,8 @@ public HandlerKey(final String url, final RequestMethod requestMethod) { } public HandlerKey(final HttpServletRequest request) { - String url = request.getRequestURI(); - RequestMethod requestMethod = RequestMethod.valueOf(request.getMethod()); - - this.url = url; - this.requestMethod = requestMethod; + this.url = request.getRequestURI(); + this.requestMethod = RequestMethod.valueOf(request.getMethod()); } public static List from(final RequestMapping requestMapping) { From bc3561c449d9d2bfc6657f142bc52cfe7589af7f Mon Sep 17 00:00:00 2001 From: devHudi Date: Mon, 26 Sep 2022 16:56:06 +0900 Subject: [PATCH 6/8] =?UTF-8?q?fix:=20Handler=EB=A5=BC=20=EC=B0=BE?= =?UTF-8?q?=EC=9D=84=20=EC=88=98=20=EC=97=86=EB=8A=94=20=EA=B2=BD=EC=9A=B0?= =?UTF-8?q?=20Exception=EC=9D=84=20=EB=8D=98=EC=A7=80=EB=8A=94=20=EB=8C=80?= =?UTF-8?q?=EC=8B=A0=20null=EC=9D=84=20=EB=B0=98=ED=99=98=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mvc/controller/tobe/AnnotationHandlerMapping.java | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/mvc/src/main/java/nextstep/mvc/controller/tobe/AnnotationHandlerMapping.java b/mvc/src/main/java/nextstep/mvc/controller/tobe/AnnotationHandlerMapping.java index b5b57e9015..6d25c4cdcc 100644 --- a/mvc/src/main/java/nextstep/mvc/controller/tobe/AnnotationHandlerMapping.java +++ b/mvc/src/main/java/nextstep/mvc/controller/tobe/AnnotationHandlerMapping.java @@ -8,7 +8,6 @@ import java.util.Map; import java.util.stream.Collectors; import nextstep.mvc.HandlerMapping; -import nextstep.mvc.controller.tobe.exception.ControllerNotFoundException; import nextstep.web.annotation.RequestMapping; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -54,14 +53,8 @@ private void addHandlerExecutions(final Method method) { } } - public Object getHandler(final HttpServletRequest request) { + public HandlerExecution getHandler(final HttpServletRequest request) { HandlerKey handlerKey = new HandlerKey(request); - HandlerExecution handlerExecution = handlerExecutions.get(handlerKey); - - if (handlerExecution == null) { - throw new ControllerNotFoundException(); - } - - return handlerExecution; + return handlerExecutions.get(handlerKey); } } From 8600d06ffa5a54884711737fb2610da2d0d54b79 Mon Sep 17 00:00:00 2001 From: devHudi Date: Mon, 26 Sep 2022 16:58:52 +0900 Subject: [PATCH 7/8] =?UTF-8?q?fix:=20request=EC=97=90=20setAttribute?= =?UTF-8?q?=EB=90=9C=20=EC=9D=B4=ED=9B=84=20forward=EA=B0=80=20=EC=8B=A4?= =?UTF-8?q?=ED=96=89=EB=90=98=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mvc/src/main/java/nextstep/mvc/view/JspView.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mvc/src/main/java/nextstep/mvc/view/JspView.java b/mvc/src/main/java/nextstep/mvc/view/JspView.java index 023192360b..a2b9f65d5d 100644 --- a/mvc/src/main/java/nextstep/mvc/view/JspView.java +++ b/mvc/src/main/java/nextstep/mvc/view/JspView.java @@ -25,11 +25,12 @@ public void render(final Map model, final HttpServletRequest request, } final var requestDispatcher = request.getRequestDispatcher(viewName); - requestDispatcher.forward(request, response); model.keySet().forEach(key -> { log.debug("attribute name : {}, value : {}", key, model.get(key)); request.setAttribute(key, model.get(key)); }); + + requestDispatcher.forward(request, response); } } From 24ab02e04ab0c3d27e459b528a0cb1811d9e7c04 Mon Sep 17 00:00:00 2001 From: devHudi Date: Mon, 26 Sep 2022 17:02:52 +0900 Subject: [PATCH 8/8] =?UTF-8?q?refactor:=20=EB=A9=94=EC=86=8C=EB=93=9C=20?= =?UTF-8?q?=EC=B6=94=EC=B6=9C=EC=9D=84=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=97=AC=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/nextstep/mvc/controller/tobe/HandlerKey.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/mvc/src/main/java/nextstep/mvc/controller/tobe/HandlerKey.java b/mvc/src/main/java/nextstep/mvc/controller/tobe/HandlerKey.java index 882892cca3..405229000d 100644 --- a/mvc/src/main/java/nextstep/mvc/controller/tobe/HandlerKey.java +++ b/mvc/src/main/java/nextstep/mvc/controller/tobe/HandlerKey.java @@ -26,9 +26,16 @@ public HandlerKey(final HttpServletRequest request) { public static List from(final RequestMapping requestMapping) { String url = requestMapping.value(); - List requestMethods = Arrays.stream(requestMapping.method()) + List requestMethods = generateRequestMethods(requestMapping); + return generateHandlerKeys(url, requestMethods); + } + + private static List generateRequestMethods(final RequestMapping requestMapping) { + return Arrays.stream(requestMapping.method()) .collect(Collectors.toList()); + } + private static List generateHandlerKeys(final String url, final List requestMethods) { List handlerKeys = new ArrayList<>(); for (RequestMethod requestMethod : requestMethods) { HandlerKey handlerKey = new HandlerKey(url, requestMethod);