Skip to content

Commit

Permalink
[@MVC 구현하기 - step 3] 필립(양재필) 미션 제출합니다. (#565)
Browse files Browse the repository at this point in the history
* refactor: render메서드 위치 이동

DispatcerServlet -> ModelAndView

* feat: JsonView render 구현

* feat: UserController 추가

* refactor: Login Conotroller 어노테이션 기반으로 변경

* refactor: logout 컨트롤러 어노테이션 기반으로 변경

* refactor: 포워딩 컨트롤러 어노테이션 기반으로 변경

* refactor: legacy 컨트롤러 제거

* refactor: DispatcherSErvlet 위치 변경

* refactor: 누락된 final추가

* refactor: static 제거

* refactor: 필요한 설정 외 제거

* feat: 핸들러를 찾을 수 없을때 404패이지 응답 구현

- 지정된 ModelAndView를 표시하는 ForwardingExcution 생성
- AnnotationHandlerMapping에 notfound용 모델앤뷰 내용 추가
- DispatcherServletInitializer 에서 404 페이지 추가

* refactor: 누락된 final추가

* fix: 여러개의 HandlerMapping추가시 NotFound가 맵핑될 수 있는 오류 가능성 제거
  • Loading branch information
pilyang authored Sep 26, 2023
1 parent 5d8ac5e commit 760f056
Show file tree
Hide file tree
Showing 18 changed files with 206 additions and 158 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import web.org.springframework.web.WebApplicationInitializer;
import webmvc.org.springframework.web.servlet.ModelAndView;
import webmvc.org.springframework.web.servlet.mvc.DispatcherServlet;
import webmvc.org.springframework.web.servlet.mvc.HandlerExecutionAdapter;
import webmvc.org.springframework.web.servlet.mvc.asis.Controller;
import webmvc.org.springframework.web.servlet.mvc.tobe.AnnotationHandlerMapping;
import webmvc.org.springframework.web.servlet.mvc.tobe.HandlerExecution;
import webmvc.org.springframework.web.servlet.view.JspView;

/**
* Base class for {@link WebApplicationInitializer}
Expand All @@ -18,15 +20,13 @@ public class DispatcherServletInitializer implements WebApplicationInitializer {
private static final Logger log = LoggerFactory.getLogger(DispatcherServletInitializer.class);

private static final String DEFAULT_SERVLET_NAME = "dispatcher";
private static final String PACKAGE_TO_SEARCH_CONTROLLER = "com.techcourse";

@Override
public void onStartup(final ServletContext servletContext) {
final var dispatcherServlet = new DispatcherServlet();
dispatcherServlet.addHandlerMapping(new ManualHandlerMapping());
dispatcherServlet.addHandlerMapping(new AnnotationHandlerMapping(PACKAGE_TO_SEARCH_CONTROLLER));
dispatcherServlet.addHandlerMapping(new AnnotationHandlerMapping(getClass().getPackageName()));
dispatcherServlet.addNotFoundModelAndView(new ModelAndView(new JspView("redirect:/404.jsp")));
dispatcherServlet.addHandlerAdapterType(HandlerExecution.class, HandlerExecutionAdapter.class);
dispatcherServlet.addHandlerAdapterType(Controller.class, ManualControllerHandlerAdapter.class);

final var registration = servletContext.addServlet(DEFAULT_SERVLET_NAME, dispatcherServlet);
if (registration == null) {
Expand Down

This file was deleted.

45 changes: 0 additions & 45 deletions app/src/main/java/com/techcourse/ManualHandlerMapping.java

This file was deleted.

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 DefaultForwardController {

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

@RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView forward(final HttpServletRequest request, final HttpServletResponse response) {
return new ModelAndView(new JspView(INDEX));
}
}
29 changes: 23 additions & 6 deletions app/src/main/java/com/techcourse/controller/LoginController.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,34 @@

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 webmvc.org.springframework.web.servlet.mvc.asis.Controller;
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.JspView;

public class LoginController implements Controller {
@Controller
public class LoginController {

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

@Override
public String execute(final HttpServletRequest req, final HttpServletResponse res) throws Exception {
@RequestMapping(value = "/login", method = RequestMethod.POST)
public ModelAndView doLogin(final HttpServletRequest req, final HttpServletResponse res) {
if (UserSession.isLoggedIn(req.getSession())) {
return "redirect:/index.jsp";
return new ModelAndView(new JspView("redirect:/index.jsp"));
}

return InMemoryUserRepository.findByAccount(req.getParameter("account"))
final String redirectPath = InMemoryUserRepository.findByAccount(req.getParameter("account"))
.map(user -> {
log.info("User : {}", user);
return login(req, user);
})
.orElse("redirect:/401.jsp");
return new ModelAndView(new JspView(redirectPath));
}

private String login(final HttpServletRequest request, final User user) {
Expand All @@ -34,4 +40,15 @@ private String login(final HttpServletRequest request, final User user) {
}
return "redirect:/401.jsp";
}

@RequestMapping(value = "/login/view", method = RequestMethod.GET)
public ModelAndView loginView(final HttpServletRequest req, final HttpServletResponse res) {
final String redirectPath = UserSession.getUserFrom(req.getSession())
.map(user -> {
log.info("logged in {}", user.getAccount());
return "redirect:/index.jsp";
})
.orElse("/login.jsp");
return new ModelAndView(new JspView(redirectPath));
}
}

This file was deleted.

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

import context.org.springframework.stereotype.Controller;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import webmvc.org.springframework.web.servlet.mvc.asis.Controller;
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;

public class LogoutController implements Controller {
@Controller
public class LogoutController {

@Override
public String execute(final HttpServletRequest req, final HttpServletResponse res) throws Exception {
@RequestMapping(value = "/logout", method = RequestMethod.GET)
public ModelAndView execute(final HttpServletRequest req, final HttpServletResponse res) {
final var session = req.getSession();
session.removeAttribute(UserSession.SESSION_KEY);
return "redirect:/";
return new ModelAndView(new JspView("redirect:/"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
public class RegisterController {

@RequestMapping(value = "/register", method = RequestMethod.POST)
public ModelAndView save(HttpServletRequest req, HttpServletResponse res) {
public ModelAndView save(final HttpServletRequest req, final HttpServletResponse res) {
final var user = new User(2,
req.getParameter("account"),
req.getParameter("password"),
Expand All @@ -24,7 +24,7 @@ public ModelAndView save(HttpServletRequest req, HttpServletResponse res) {
}

@RequestMapping(value = "/register/view", method = RequestMethod.GET)
public ModelAndView show(HttpServletRequest req, HttpServletResponse res) {
public ModelAndView show(final HttpServletRequest req, final HttpServletResponse res) {
return new ModelAndView(new JspView("/register.jsp"));
}
}
34 changes: 34 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,34 @@
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(final HttpServletRequest request, final HttpServletResponse response) {
final String account = request.getParameter("account");
log.debug("user id : {}", account);

final ModelAndView modelAndView = new ModelAndView(new JsonView());
final User user = InMemoryUserRepository.findByAccount(account)
.orElseThrow();
log.info("user : {}", user);

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

Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package webmvc.org.springframework.web.servlet;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
Expand All @@ -19,6 +22,10 @@ public ModelAndView addObject(final String attributeName, final Object attribute
return this;
}

public void render(final HttpServletRequest request, HttpServletResponse response) throws Exception {
view.render(model, request, response);
}

public Object getObject(final String attributeName) {
return model.get(attributeName);
}
Expand Down
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,13 +7,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import webmvc.org.springframework.web.servlet.ModelAndView;
import webmvc.org.springframework.web.servlet.View;
import webmvc.org.springframework.web.servlet.mvc.HandlerAdapter;
import webmvc.org.springframework.web.servlet.mvc.HandlerAdapterFactory;
import webmvc.org.springframework.web.servlet.mvc.HandlerMapping;
import webmvc.org.springframework.web.servlet.mvc.HandlerMappings;

import java.util.Map;

public class DispatcherServlet extends HttpServlet {

Expand All @@ -32,6 +25,10 @@ public void addHandlerMapping(final HandlerMapping handlerMapping) {
handlerMappings.add(handlerMapping);
}

public void addNotFoundModelAndView(final ModelAndView modelAndView) {
handlerMappings.addNotFoundHandlerMapping(new SimpleForwardingHandlerMapping(modelAndView));
}

public void addHandlerAdapterType(final Class<?> handlerType, final Class<? extends HandlerAdapter> adapterType) {
handlerAdapterFactory.addAdapterType(handlerType, adapterType);
}
Expand All @@ -49,16 +46,11 @@ protected void service(final HttpServletRequest request, final HttpServletRespon
final Object handler = handlerMappings.getHandler(request);
final HandlerAdapter adapter = handlerAdapterFactory.getAdapter(handler);
final ModelAndView modelAndView = adapter.handle(request, response);
render(modelAndView, request, response);
modelAndView.render(request, response);

} catch (Exception e) {
log.error("Exception : {}", e.getMessage(), e);
throw new ServletException(e.getMessage());
}
}

private void render(final ModelAndView modelAndView, final HttpServletRequest request, final HttpServletResponse response) throws Exception {
final View view = modelAndView.getView();
final Map<String, Object> model = modelAndView.getModel();
view.render(model, request, response);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package webmvc.org.springframework.web.servlet.mvc;

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

public class ForwardingExecution extends HandlerExecution {

private final ModelAndView modelAndView;

public ForwardingExecution(final ModelAndView modelAndView) {
super(null, null);
this.modelAndView = modelAndView;
}

@Override
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response) throws Exception {
return modelAndView;
}
}
Loading

0 comments on commit 760f056

Please sign in to comment.