Skip to content

Commit b67953b

Browse files
authored
[MVC 미션 2단계] 오리(오현서) 미션 제출합니다. (#451)
* refactor: RequestMapping Method default 값 추가 * refactor: Handler가 null이면 throws * refactor: 메소드명 변경 * refactor: 메소드명 변경 * feat: Register 로직을 annotation으로 처리 * refactor: HandlerMapping 인터페이스 추가 * refactor: HandlerMappings 일급 컬렉션 활용하도록 변경 * feat: HandlerAdapter 추가 * refactor: HandelrAdpaters - > HandlerAdapterFinder 클래스명 변경 * refactor: 핸들러 찾지 못할 시 예외 * refactor: 가독성 개선 * feat: 예외 처리 추가 * chore: 패키지 분리 * refactor: 개행, 컨벤션등 수정 * refactor: HandlerMappings -> HandlerMappingComposite 변경 * chore: ManualHandlerAdapter 패키지 변경 * refactor: AnnotationHandlerMapping의 패키지 스캔 범위 구체화 * refactor: 예외 처리 로직 메소드 추출
1 parent 2c998b9 commit b67953b

23 files changed

+279
-90
lines changed

app/src/main/java/com/techcourse/DispatcherServlet.java

Lines changed: 50 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,48 +4,80 @@
44
import jakarta.servlet.http.HttpServlet;
55
import jakarta.servlet.http.HttpServletRequest;
66
import jakarta.servlet.http.HttpServletResponse;
7+
import java.util.List;
78
import org.slf4j.Logger;
89
import org.slf4j.LoggerFactory;
9-
import webmvc.org.springframework.web.servlet.view.JspView;
10+
import webmvc.org.springframework.web.servlet.ModelAndView;
11+
import webmvc.org.springframework.web.servlet.View;
12+
import webmvc.org.springframework.web.servlet.mvc.asis.ManualHandlerAdapter;
13+
import webmvc.org.springframework.web.servlet.mvc.tobe.adapter.AnnotationHandlerAdapter;
14+
import webmvc.org.springframework.web.servlet.mvc.tobe.adapter.HandlerAdapter;
15+
import webmvc.org.springframework.web.servlet.mvc.tobe.adapter.HandlerAdapterFinder;
16+
import webmvc.org.springframework.web.servlet.mvc.tobe.exception.ExceptionResolver;
17+
import webmvc.org.springframework.web.servlet.mvc.tobe.handler.AnnotationHandlerMapping;
18+
import webmvc.org.springframework.web.servlet.mvc.tobe.handler.HandlerMapping;
19+
import webmvc.org.springframework.web.servlet.mvc.tobe.handler.HandlerMappingComposite;
1020

1121
public class DispatcherServlet extends HttpServlet {
1222

1323
private static final long serialVersionUID = 1L;
1424
private static final Logger log = LoggerFactory.getLogger(DispatcherServlet.class);
1525

16-
private ManualHandlerMapping manualHandlerMapping;
26+
private HandlerMapping handlerMapping;
27+
private HandlerAdapterFinder handlerAdapterFinder;
28+
private ExceptionResolver exceptionResolver;
1729

1830
public DispatcherServlet() {
1931
}
2032

2133
@Override
2234
public void init() {
23-
manualHandlerMapping = new ManualHandlerMapping();
24-
manualHandlerMapping.initialize();
35+
handlerMapping = initHandlerMappings();
36+
handlerAdapterFinder = initHandlerAdapterFinder();
37+
exceptionResolver = new ExceptionResolver();
38+
}
39+
40+
private HandlerMapping initHandlerMappings() {
41+
HandlerMapping handlerMapping = new HandlerMappingComposite(
42+
List.of(new ManualHandlerMapping(), new AnnotationHandlerMapping("com.techcourse.controller")));
43+
handlerMapping.initialize();
44+
return handlerMapping;
45+
}
46+
47+
private HandlerAdapterFinder initHandlerAdapterFinder() {
48+
return new HandlerAdapterFinder(
49+
List.of(new ManualHandlerAdapter(), new AnnotationHandlerAdapter()));
2550
}
2651

2752
@Override
28-
protected void service(final HttpServletRequest request, final HttpServletResponse response) throws ServletException {
53+
protected void service(final HttpServletRequest request, final HttpServletResponse response)
54+
throws ServletException {
2955
final String requestURI = request.getRequestURI();
3056
log.debug("Method : {}, Request URI : {}", request.getMethod(), requestURI);
31-
3257
try {
33-
final var controller = manualHandlerMapping.getHandler(requestURI);
34-
final var viewName = controller.execute(request, response);
35-
move(viewName, request, response);
58+
Object handler = handlerMapping.getHandler(request);
59+
HandlerAdapter handlerAdapter = handlerAdapterFinder.find(handler);
60+
ModelAndView mv = handlerAdapter.handle(request, response, handler);
61+
render(request, response, mv);
3662
} catch (Throwable e) {
37-
log.error("Exception : {}", e.getMessage(), e);
38-
throw new ServletException(e.getMessage());
63+
handleException(request, response, e);
3964
}
4065
}
4166

42-
private void move(final String viewName, final HttpServletRequest request, final HttpServletResponse response) throws Exception {
43-
if (viewName.startsWith(JspView.REDIRECT_PREFIX)) {
44-
response.sendRedirect(viewName.substring(JspView.REDIRECT_PREFIX.length()));
45-
return;
46-
}
67+
private void render(HttpServletRequest request, HttpServletResponse response, ModelAndView modelAndView)
68+
throws Exception {
69+
View view = modelAndView.getView();
70+
view.render(modelAndView.getModel(), request, response);
71+
}
4772

48-
final var requestDispatcher = request.getRequestDispatcher(viewName);
49-
requestDispatcher.forward(request, response);
73+
private void handleException(HttpServletRequest request, HttpServletResponse response, Throwable e)
74+
throws ServletException {
75+
ModelAndView mv = exceptionResolver.handle(e);
76+
try {
77+
render(request, response, mv);
78+
} catch (Exception ex) {
79+
log.error("Exception : {}", e.getMessage(), e);
80+
throw new ServletException(e.getMessage());
81+
}
5082
}
5183
}

app/src/main/java/com/techcourse/ManualHandlerMapping.java

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,38 @@
11
package com.techcourse;
22

3-
import com.techcourse.controller.*;
3+
import com.techcourse.controller.manual.LoginController;
4+
import com.techcourse.controller.manual.LoginViewController;
5+
import com.techcourse.controller.manual.LogoutController;
6+
import jakarta.servlet.http.HttpServletRequest;
7+
import java.util.HashMap;
8+
import java.util.Map;
49
import org.slf4j.Logger;
510
import org.slf4j.LoggerFactory;
611
import webmvc.org.springframework.web.servlet.mvc.asis.Controller;
712
import webmvc.org.springframework.web.servlet.mvc.asis.ForwardController;
13+
import webmvc.org.springframework.web.servlet.mvc.tobe.handler.HandlerMapping;
814

9-
import java.util.HashMap;
10-
import java.util.Map;
11-
12-
public class ManualHandlerMapping {
15+
public class ManualHandlerMapping implements HandlerMapping<Controller> {
1316

1417
private static final Logger log = LoggerFactory.getLogger(ManualHandlerMapping.class);
1518

1619
private static final Map<String, Controller> controllers = new HashMap<>();
1720

21+
@Override
1822
public void initialize() {
1923
controllers.put("/", new ForwardController("/index.jsp"));
2024
controllers.put("/login", new LoginController());
2125
controllers.put("/login/view", new LoginViewController());
2226
controllers.put("/logout", new LogoutController());
23-
controllers.put("/register/view", new RegisterViewController());
24-
controllers.put("/register", new RegisterController());
2527

2628
log.info("Initialized Handler Mapping!");
2729
controllers.keySet()
28-
.forEach(path -> log.info("Path : {}, Controller : {}", path, controllers.get(path).getClass()));
30+
.forEach(path -> log.info("Path : {}, Controller : {}", path, controllers.get(path).getClass()));
2931
}
3032

31-
public Controller getHandler(final String requestURI) {
33+
@Override
34+
public Controller getHandler(final HttpServletRequest request) {
35+
String requestURI = request.getRequestURI();
3236
log.debug("Request Mapping Uri : {}", requestURI);
3337
return controllers.get(requestURI);
3438
}

app/src/main/java/com/techcourse/controller/RegisterController.java

Lines changed: 0 additions & 21 deletions
This file was deleted.

app/src/main/java/com/techcourse/controller/RegisterViewController.java

Lines changed: 0 additions & 13 deletions
This file was deleted.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.techcourse.controller.annotation;
2+
3+
import com.techcourse.domain.User;
4+
import com.techcourse.repository.InMemoryUserRepository;
5+
import context.org.springframework.stereotype.Controller;
6+
import jakarta.servlet.http.HttpServletRequest;
7+
import jakarta.servlet.http.HttpServletResponse;
8+
import web.org.springframework.web.bind.annotation.RequestMapping;
9+
import web.org.springframework.web.bind.annotation.RequestMethod;
10+
import webmvc.org.springframework.web.servlet.ModelAndView;
11+
import webmvc.org.springframework.web.servlet.view.JspView;
12+
13+
@Controller
14+
public class RegisterController {
15+
16+
@RequestMapping(value = "/register", method = RequestMethod.POST)
17+
public ModelAndView save(HttpServletRequest req, HttpServletResponse res) {
18+
final var user = new User(2,
19+
req.getParameter("account"),
20+
req.getParameter("password"),
21+
req.getParameter("email"));
22+
InMemoryUserRepository.save(user);
23+
24+
return new ModelAndView(new JspView("redirect:/index.jsp"));
25+
}
26+
27+
@RequestMapping(value = "/register", method = RequestMethod.GET)
28+
public ModelAndView show(HttpServletRequest req, HttpServletResponse res) {
29+
return new ModelAndView(new JspView("/register.jsp"));
30+
}
31+
}

app/src/main/java/com/techcourse/controller/LoginController.java renamed to app/src/main/java/com/techcourse/controller/manual/LoginController.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
package com.techcourse.controller;
1+
package com.techcourse.controller.manual;
22

3+
import com.techcourse.controller.UserSession;
34
import com.techcourse.domain.User;
45
import com.techcourse.repository.InMemoryUserRepository;
56
import jakarta.servlet.http.HttpServletRequest;
67
import jakarta.servlet.http.HttpServletResponse;
7-
import webmvc.org.springframework.web.servlet.mvc.asis.Controller;
88
import org.slf4j.Logger;
99
import org.slf4j.LoggerFactory;
10+
import webmvc.org.springframework.web.servlet.mvc.asis.Controller;
1011

1112
public class LoginController implements Controller {
1213

app/src/main/java/com/techcourse/controller/LoginViewController.java renamed to app/src/main/java/com/techcourse/controller/manual/LoginViewController.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
package com.techcourse.controller;
1+
package com.techcourse.controller.manual;
22

3+
import com.techcourse.controller.UserSession;
34
import jakarta.servlet.http.HttpServletRequest;
45
import jakarta.servlet.http.HttpServletResponse;
56
import org.slf4j.Logger;

app/src/main/java/com/techcourse/controller/LogoutController.java renamed to app/src/main/java/com/techcourse/controller/manual/LogoutController.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
package com.techcourse.controller;
1+
package com.techcourse.controller.manual;
22

3+
import com.techcourse.controller.UserSession;
34
import jakarta.servlet.http.HttpServletRequest;
45
import jakarta.servlet.http.HttpServletResponse;
56
import webmvc.org.springframework.web.servlet.mvc.asis.Controller;

mvc/src/main/java/web/org/springframework/web/bind/annotation/RequestMapping.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@
1010
public @interface RequestMapping {
1111
String value() default "";
1212

13-
RequestMethod[] method() default {};
13+
RequestMethod[] method() default {RequestMethod.GET};
1414
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package webmvc.org.springframework.web.servlet.mvc.asis;
2+
3+
import jakarta.servlet.http.HttpServletRequest;
4+
import jakarta.servlet.http.HttpServletResponse;
5+
import webmvc.org.springframework.web.servlet.ModelAndView;
6+
import webmvc.org.springframework.web.servlet.mvc.tobe.adapter.HandlerAdapter;
7+
import webmvc.org.springframework.web.servlet.view.JspView;
8+
9+
public class ManualHandlerAdapter implements HandlerAdapter {
10+
11+
@Override
12+
public boolean supports(Object handler) {
13+
return handler instanceof Controller;
14+
}
15+
16+
@Override
17+
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
18+
throws Exception {
19+
String responseURI = ((Controller) handler).execute(request, response);
20+
ModelAndView modelAndView = new ModelAndView(new JspView(responseURI));
21+
return modelAndView;
22+
}
23+
}

0 commit comments

Comments
 (0)