Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MVC 구현하기 - 3단계] 엔초(권예진) 미션 제출합니다. #575

Merged
merged 11 commits into from
Sep 26, 2023
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import web.org.springframework.web.WebApplicationInitializer;
import webmvc.org.springframework.web.servlet.mvc.tobe.AnnotationHandlerMapping;
import webmvc.org.springframework.web.servlet.mvc.DispatcherServlet;
import webmvc.org.springframework.web.servlet.mvc.tobe.HandlerExecutionHandlerAdapter;

/**
* Base class for {@link WebApplicationInitializer}
Expand All @@ -18,6 +21,8 @@ public class DispatcherServletInitializer implements WebApplicationInitializer {
@Override
public void onStartup(final ServletContext servletContext) {
final var dispatcherServlet = new DispatcherServlet();
dispatcherServlet.addHandlerMapping(new AnnotationHandlerMapping(Application.class.getPackageName() + ".*"));
dispatcherServlet.addHandlerAdapter(new HandlerExecutionHandlerAdapter());

final var registration = servletContext.addServlet(DEFAULT_SERVLET_NAME, dispatcherServlet);
if (registration == null) {
Expand Down
52 changes: 0 additions & 52 deletions app/src/main/java/com/techcourse/ManualHandlerMapping.java

This file was deleted.

20 changes: 20 additions & 0 deletions app/src/main/java/com/techcourse/controller/ForwardController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.techcourse.controller;

import context.org.springframework.stereotype.Controller;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import web.org.springframework.web.bind.annotation.RequestMapping;
import web.org.springframework.web.bind.annotation.RequestMethod;
import webmvc.org.springframework.web.servlet.ModelAndView;
import webmvc.org.springframework.web.servlet.view.JspView;

@Controller
public class ForwardController {

private static final String PATH = "/index.jsp";

@RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView execute(final HttpServletRequest request, final HttpServletResponse response) {
return new ModelAndView(new JspView(PATH));
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.techcourse.controller.annotation_controller;
package com.techcourse.controller;

import com.techcourse.controller.UserSession;
import com.techcourse.domain.User;
import com.techcourse.repository.InMemoryUserRepository;
import context.org.springframework.stereotype.Controller;
Expand All @@ -14,9 +13,9 @@
import webmvc.org.springframework.web.servlet.view.JspView;

@Controller
public class LoginAnnotationController {
public class LoginController {

private static final Logger log = LoggerFactory.getLogger(LoginAnnotationController.class);
private static final Logger log = LoggerFactory.getLogger(LoginController.class);

@RequestMapping(value = "/login", method = RequestMethod.POST)
public ModelAndView executePostLogin(final HttpServletRequest req, final HttpServletResponse res) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.techcourse.controller.annotation_controller;
package com.techcourse.controller;

import com.techcourse.controller.UserSession;
import context.org.springframework.stereotype.Controller;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
Expand All @@ -10,7 +9,7 @@
import webmvc.org.springframework.web.servlet.view.JspView;

@Controller
public class LogoutAnnotationController {
public class LogoutController {

@RequestMapping(value = "/logout", method = RequestMethod.GET)
public ModelAndView executeGetLogout(final HttpServletRequest req, final HttpServletResponse res) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.techcourse.controller.annotation_controller;
package com.techcourse.controller;

import com.techcourse.domain.User;
import com.techcourse.repository.InMemoryUserRepository;
Expand All @@ -11,7 +11,7 @@
import webmvc.org.springframework.web.servlet.view.JspView;

@Controller
public class RegisterAnnotationController {
public class RegisterController {

@RequestMapping(value = "/register", method = RequestMethod.POST)
public ModelAndView executePostRegister(final HttpServletRequest req, final HttpServletResponse res) {
Expand Down
32 changes: 32 additions & 0 deletions app/src/main/java/com/techcourse/controller/UserController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.techcourse.controller;

import com.techcourse.domain.User;
import com.techcourse.repository.InMemoryUserRepository;
import context.org.springframework.stereotype.Controller;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import web.org.springframework.web.bind.annotation.RequestMapping;
import web.org.springframework.web.bind.annotation.RequestMethod;
import webmvc.org.springframework.web.servlet.ModelAndView;
import webmvc.org.springframework.web.servlet.view.JsonView;

@Controller
public class UserController {

private static final Logger log = LoggerFactory.getLogger(UserController.class);

@RequestMapping(value = "/api/user", method = RequestMethod.GET)
public ModelAndView show(HttpServletRequest request, HttpServletResponse response) {
final String account = request.getParameter("account");
log.info("user id : {}", account);

final ModelAndView modelAndView = new ModelAndView(new JsonView());
final User user = InMemoryUserRepository.findByAccount(account)
.orElseThrow();

modelAndView.addObject("user", user);
return modelAndView;
}
}

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.techcourse;
package webmvc.org.springframework.web.servlet.mvc;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
Expand All @@ -7,12 +7,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import webmvc.org.springframework.web.servlet.ModelAndView;
import webmvc.org.springframework.web.servlet.mvc.HandlerAdapter;
import webmvc.org.springframework.web.servlet.mvc.HandlerAdapterRegistry;
import webmvc.org.springframework.web.servlet.mvc.HandlerMappingRegistry;
import webmvc.org.springframework.web.servlet.mvc.asis.ControllerHandlerAdapter;
import webmvc.org.springframework.web.servlet.mvc.tobe.AnnotationHandlerMapping;
import webmvc.org.springframework.web.servlet.mvc.tobe.HandlerExecutionHandlerAdapter;
import webmvc.org.springframework.web.servlet.view.JspView;

import java.util.Optional;

Expand All @@ -23,34 +18,39 @@ public class DispatcherServlet extends HttpServlet {

private final HandlerMappingRegistry handlerMappingRegistry = new HandlerMappingRegistry();
private final HandlerAdapterRegistry handlerAdapterRegistry = new HandlerAdapterRegistry();
private HandlerExecutor handlerExecutor;

public DispatcherServlet() {
}

@Override
public void init() {
handlerMappingRegistry.addHandlerMapping(new ManualHandlerMapping());
handlerMappingRegistry.addHandlerMapping(new AnnotationHandlerMapping(Application.class.getPackageName() + ".*"));
handlerAdapterRegistry.addHandlerAdapter(new ControllerHandlerAdapter());
handlerAdapterRegistry.addHandlerAdapter(new HandlerExecutionHandlerAdapter());
handlerExecutor = new HandlerExecutor(handlerAdapterRegistry);
}

public void addHandlerMapping(final HandlerMapping handlerMapping) {
handlerMappingRegistry.addHandlerMapping(handlerMapping);
}

public void addHandlerAdapter(final HandlerAdapter handlerAdapter) {
handlerAdapterRegistry.addHandlerAdapter(handlerAdapter);
}
Comment on lines 26 to 36

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재 이 부분을 보면 HandlerExecutor의 경우 DispatcherServlet init()메소드에서 초기화가 되는데
HandlerMappingHandlerAdapter의 경우에는 DispatcherServletInitializer에서 값을 추가하는 방식으로 구현을 해주셨어요. 이 부분을 분리해서 값을 추가해주신 이유가 있을까요?
혹시 AnnotationHandler의 basePackage 설정을 위함일까요?
엔초의 생각흐름이 궁금합니다!☺️

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addHandlerMappingaddHandlerAdapterDispatcherServletInitializeronStartUp()에서 직접 호출하고 있고, DispatcherServletinit()onStartUp()이 끝난 후에 호출이 되고 있습니다.

HandlerExecutorHandlerAdapterRegistry를 사용하기 때문에 HandlerAdapterRegistry에 대한 설정이 끝난 이후에 사용되어야 한다고 생각했습니다. init() 메서드가 HandlerAdapterRegistry를 설정해주는 onStartUp()이 끝난 후에 호출되기 때문에 이렇게 분리하면 더 명확하다고 생각했습니다.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 이해 완료했습니다! 자세하게 답변해주셔서 감사합니다!


@Override
protected void service(final HttpServletRequest request, final HttpServletResponse response) {
protected void service(final HttpServletRequest request, final HttpServletResponse response) throws ServletException {
final String requestURI = request.getRequestURI();
log.debug("Method : {}, Request URI : {}", request.getMethod(), requestURI);

final Optional<Object> nullableHandler = handlerMappingRegistry.getHandler(request);

if (nullableHandler.isEmpty()) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
render(new ModelAndView(new JspView("404.jsp")), request, response);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍👍

return;
}

final Object handler = nullableHandler.get();
try {
final HandlerAdapter handlerAdapter = handlerAdapterRegistry.getHandlerAdapter(handler);
final ModelAndView modelAndView = handlerAdapter.handle(request, response, handler);
final ModelAndView modelAndView = handlerExecutor.handle(request, response, handler);
render(modelAndView, request, response);
} catch (Exception e) {
throw new RuntimeException(e);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이번에 HandlerExecutor를 이번에 도입해주셨는데 HandlerExecutor 내부에 HanderMappingResitry를 가지고 있고 handler를 찾아와서 실행시켜주는 것 같습니다. 하지만 현재 코드를 보면 404.jsp를 나타낼 때에는 handlerMappingResitry에서 직접꺼내와서 작업을 진행하는 것도 작업이 있는데 이 부분도 HandlerExecutor 내부에서 처리하는 방식으로 수정하면 좋을 것 같습니다!☺️

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handleNotFound 메서드를 추가해서 404 ModelAndView를 반환하도록 수정했습니다!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

확인했습니다!

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package webmvc.org.springframework.web.servlet.mvc;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import webmvc.org.springframework.web.servlet.ModelAndView;

public class HandlerExecutor {

private final HandlerAdapterRegistry handlerAdapterRegistry;

public HandlerExecutor(final HandlerAdapterRegistry handlerAdapterRegistry) {
this.handlerAdapterRegistry = handlerAdapterRegistry;
}

public ModelAndView handle(final HttpServletRequest request, final HttpServletResponse response, Object handler) throws Exception {
final HandlerAdapter handlerAdapter = handlerAdapterRegistry.getHandlerAdapter(handler);
return handlerAdapter.handle(request, response, handler);
}
}

This file was deleted.

Loading