Skip to content

Commit

Permalink
[MVC 구현하기 - 3단계] 루쿠(백경환) 미션 제출합니다. (#621)
Browse files Browse the repository at this point in the history
* 패키지 위치 변경 및 코드 정리

* refactor: 메서드 분리

* refactor: 공백 제거

* refactor: 상수화

* feat: JspView 구현

* feat: JsonView 구현

* refactor: 레거시 컨트롤러 -> 어노테이션 기반 컨트롤러로 변경

* refactor: 레거시 코드 제거

* refactor: 패키지 이동

* refactor: 메서드명 수정

* refactor: ObjectMapper static화

---------

Co-authored-by: kang-hyungu <hkkang@woowahan.com>
  • Loading branch information
aiaiaiai1 and kang-hyungu authored Sep 30, 2023
1 parent 4e7e3cd commit b702ff3
Show file tree
Hide file tree
Showing 18 changed files with 170 additions and 190 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import web.org.springframework.web.WebApplicationInitializer;
import webmvc.org.springframework.web.servlet.DispatcherServlet;

/**
* Base class for {@link WebApplicationInitializer}
Expand Down
48 changes: 0 additions & 48 deletions app/src/main/java/com/techcourse/ManualHandlerMapping.java

This file was deleted.

18 changes: 18 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,18 @@
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 {

@RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView execute(final HttpServletRequest request, final HttpServletResponse response) {
return new ModelAndView(new JspView("/index.jsp"));
}
}
30 changes: 17 additions & 13 deletions app/src/main/java/com/techcourse/controller/LoginController.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,40 @@

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 {
if (UserSession.isLoggedIn(req.getSession())) {
return "redirect:/index.jsp";
@RequestMapping(value = "/login", method = RequestMethod.POST)
public ModelAndView login(final HttpServletRequest request, final HttpServletResponse response) throws Exception {
if (UserSession.isLoggedIn(request.getSession())) {
return new ModelAndView(new JspView("redirect:/index.jsp"));
}

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

private String login(final HttpServletRequest request, final User user) {
private ModelAndView login(final HttpServletRequest request, final User user) {
if (user.checkPassword(request.getParameter("password"))) {
final var session = request.getSession();
session.setAttribute(UserSession.SESSION_KEY, user);
return "redirect:/index.jsp";
return new ModelAndView(new JspView("redirect:/index.jsp"));
}
return "redirect:/401.jsp";
return new ModelAndView(new JspView("redirect:/401.jsp"));
}
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
package com.techcourse.controller;

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 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 LoginViewController implements Controller {
@Controller
public class LoginViewController {

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

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

}
18 changes: 12 additions & 6 deletions app/src/main/java/com/techcourse/controller/LogoutController.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
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 {
final var session = req.getSession();
@RequestMapping(value = "/logout", method = RequestMethod.GET)
public ModelAndView logout(final HttpServletRequest request, final HttpServletResponse response) throws Exception {
final var session = request.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 @@ -2,20 +2,25 @@

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 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 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 register(final HttpServletRequest request, final HttpServletResponse response) throws Exception {
final var user = new User(2,
req.getParameter("account"),
req.getParameter("password"),
req.getParameter("email"));
request.getParameter("account"),
request.getParameter("password"),
request.getParameter("email"));
InMemoryUserRepository.save(user);

return "redirect:/index.jsp";
return new ModelAndView(new JspView("redirect:/index.jsp"));
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
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 RegisterViewController implements Controller {
@Controller
public class RegisterViewController {

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

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

modelAndView.addObject("user", user);
return modelAndView;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.techcourse;
package webmvc.org.springframework.web.servlet;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
Expand All @@ -8,18 +8,16 @@
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import webmvc.org.springframework.web.servlet.ModelAndView;
import webmvc.org.springframework.web.servlet.mvc.tobe.AnnotationHandlerAdapter;
import webmvc.org.springframework.web.servlet.mvc.tobe.AnnotationHandlerMapping;
import webmvc.org.springframework.web.servlet.mvc.tobe.HandlerAdapter;
import webmvc.org.springframework.web.servlet.mvc.tobe.HandlerMapping;
import webmvc.org.springframework.web.servlet.mvc.tobe.ManualHandlerAdapter;
import webmvc.org.springframework.web.servlet.view.JspView;

public class DispatcherServlet extends HttpServlet {

private static final long serialVersionUID = 1L;
private static final Logger log = LoggerFactory.getLogger(DispatcherServlet.class);
public static final String ANNOTATION_BASE_PACKAGE = "com.techcourse.controller";
private List<HandlerMapping> handlerMappings = new ArrayList<>();
private List<HandlerAdapter> handlerAdapters = new ArrayList<>();

Expand All @@ -28,12 +26,10 @@ public DispatcherServlet() {

@Override
public void init() {
handlerMappings.add(new ManualHandlerMapping());
handlerMappings.add(new AnnotationHandlerMapping("com.techcourse.controller"));
handlerMappings.add(new AnnotationHandlerMapping(ANNOTATION_BASE_PACKAGE));
handlerMappings.forEach(HandlerMapping::initialize);

handlerAdapters.add(new AnnotationHandlerAdapter());
handlerAdapters.add(new ManualHandlerAdapter());
}

@Override
Expand All @@ -45,8 +41,8 @@ protected void service(

try {
ModelAndView modelAndView = execute(request, response);
String viewName = modelAndView.getView().getName();
move(viewName, request, response);
View view = modelAndView.getView();
view.render(modelAndView.getModel(), request, response);
} catch (Throwable e) {
log.error("Exception : {}", e.getMessage(), e);
throw new ServletException(e.getMessage());
Expand All @@ -57,31 +53,25 @@ private ModelAndView execute(
HttpServletRequest request,
HttpServletResponse response
) throws Exception {
Object handler = handlerMappings.stream()
.filter(handlerMapping -> handlerMapping.isMatch(request))
.findAny()
.orElseThrow(() -> new IllegalArgumentException("지원하지 않는 요청입니다."))
.getHandler(request);
Object handler = getHandler(request);
HandlerAdapter adapter = getHandlerAdapter(handler);
return adapter.handle(request, response, handler);
}

private HandlerAdapter getHandlerAdapter(Object handler) {
HandlerAdapter adapter = handlerAdapters.stream()
.filter(handlerAdapter -> handlerAdapter.supports(handler))
.findAny()
.orElseThrow(() -> new IllegalArgumentException("지원하지 않는 요청입니다."));

return adapter.handle(request, response, handler);
return adapter;
}

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);
private Object getHandler(HttpServletRequest request) {
Object handler = handlerMappings.stream()
.filter(handlerMapping -> handlerMapping.isMatch(request))
.findAny()
.orElseThrow(() -> new IllegalArgumentException("지원하지 않는 요청입니다."))
.getHandler(request);
return handler;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,4 @@ public Map<String, Object> getModel() {
public View getView() {
return view;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,4 @@

public interface View {
void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception;
String getName();
}
Loading

0 comments on commit b702ff3

Please sign in to comment.