-
Notifications
You must be signed in to change notification settings - Fork 302
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단계] 여우(조승현) 미션 제출합니다 #618
Changes from 6 commits
901f174
323ec1d
820af64
93bd636
8198b16
5b901d3
8f3e15a
aebcfeb
7641ee5
8f33d16
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
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; | ||
|
||
@Controller | ||
public class IndexViewController { | ||
|
||
@RequestMapping(value = "/", method = RequestMethod.GET) | ||
public String execute(final HttpServletRequest req, final HttpServletResponse res) throws Exception { | ||
return "/index.jsp"; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
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; | ||
} | ||
} | ||
|
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
package web.org.springframework.http; | ||
|
||
public class MediaType { | ||
public static final String TEXT_PLAIN_UTF8_VALUE = "text/plain;charset=UTF-8"; | ||
public static final String APPLICATION_JSON_UTF8_VALUE = "application/json;charset=UTF-8"; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,7 @@ | ||
package com.techcourse; | ||
package webmvc.org.springframework.web.servlet; | ||
|
||
import com.techcourse.controlleradapter.ControllerHandlerAdapter; | ||
import com.techcourse.exception.HandlerAdapterNotFoundException; | ||
import com.techcourse.exception.HandlerNotFoundException; | ||
import webmvc.org.springframework.web.servlet.exception.HandlerAdapterNotFoundException; | ||
import webmvc.org.springframework.web.servlet.exception.HandlerNotFoundException; | ||
import jakarta.servlet.ServletException; | ||
import jakarta.servlet.http.HttpServlet; | ||
import jakarta.servlet.http.HttpServletRequest; | ||
|
@@ -11,13 +10,10 @@ | |
import java.util.Objects; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import webmvc.org.springframework.web.servlet.ExceptionHandlerMapping; | ||
import webmvc.org.springframework.web.servlet.HandlerMapping; | ||
import webmvc.org.springframework.web.servlet.mvc.HandlerAdapter; | ||
import webmvc.org.springframework.web.servlet.mvc.tobe.AnnotationExceptionHandlerMapping; | ||
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; | ||
|
||
public class DispatcherServlet extends HttpServlet { | ||
|
||
|
@@ -29,13 +25,11 @@ public class DispatcherServlet extends HttpServlet { | |
); | ||
|
||
private List<HandlerMapping> handlerMappings = List.of( | ||
new ManualHandlerMapping(), | ||
new AnnotationHandlerMapping("com/techcourse") | ||
); | ||
|
||
private List<HandlerAdapter> handlerAdapters = List.of( | ||
new HandlerExecutionHandlerAdapter(), | ||
new ControllerHandlerAdapter() | ||
new HandlerExecutionHandlerAdapter() | ||
); | ||
|
||
public DispatcherServlet() { | ||
|
@@ -60,8 +54,8 @@ protected void service(final HttpServletRequest request, final HttpServletRespon | |
final Object handler = findHandler(request); | ||
|
||
final HandlerAdapter handlerAdapter = findHandlerAdaptor(handler); | ||
final String viewPath = handlerAdapter.invoke(handler, request, response); | ||
move(viewPath, request, response); | ||
final ModelAndView modelAndView = handlerAdapter.invoke(handler, request, response); | ||
modelAndView.getView().render(modelAndView.getModel(), request, response); | ||
} catch (Throwable e) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. view와 model을 가져오지 않고 ModelAndView에서 render를 수행해주는 방향으로 가면 어떨까요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 오,, 캡슐화! |
||
handleException(request, response, e); | ||
} | ||
|
@@ -86,19 +80,8 @@ private HandlerAdapter findHandlerAdaptor(final Object handler) { | |
throw new HandlerAdapterNotFoundException("Handler Adaptor Not found"); | ||
} | ||
|
||
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 void handleException(final HttpServletRequest request, final HttpServletResponse response, final Throwable e) { | ||
try { | ||
Object handler = null; | ||
try {Object handler = null; | ||
for (ExceptionHandlerMapping exceptionHandlerMapping : exceptionHandlerMappings) { | ||
final Object foundHandler = findExceptionHandler(e, exceptionHandlerMapping); | ||
if (Objects.nonNull(foundHandler)) { | ||
|
@@ -111,8 +94,8 @@ private void handleException(final HttpServletRequest request, final HttpServlet | |
throw new ServletException("ExceptionHandler Not Found."); | ||
} | ||
final HandlerAdapter handlerAdapter = findHandlerAdaptor(handler); | ||
final String viewPath = handlerAdapter.invoke(handler, request, response); | ||
move(viewPath, request, response); | ||
final ModelAndView modelAndView = handlerAdapter.invoke(handler, request, response); | ||
modelAndView.getView().render(modelAndView.getModel(), request, response); | ||
} catch (Exception exception) { | ||
log.error("Exception caused in ExceptionHandler"); | ||
throw new RuntimeException(e); | ||
|
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DispatcherServlet
에서 필요한 필드인exceptionHandlerMappings
,handlerMappings
,handlerAdapters
를DispatcherServletInitializer
에서 주입 시켜주시는 것에 대해 어떻게 생각하시나요?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
추가적으로 미션 2 힌트를 보셨을까요?
해당 미션 힌트에는
HandlerAdapterRegistry
와HandlerMappingRegitry
가 있었는데, 적용하지 않은 이유가 있을까요?적용한다면
findHandler
,findHandlerAdaptor
역할을 넘길 수 있을지도..?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2단계 진행 도중 힌트가 삭제돼서 Registry의 존재를 잊고 있었네요!
Registrty들을 사용해서 HandlerMapping들과 HandlerAdapter에 대한 관리 책임을 외부로 옮겼습니다.
혹시 DispatcherServlet 입장에서는
본인이 사용하는 객체에 대한 책임이 외부로 옮겨지는 것이니
이런 걸 IOC라고 부르는 걸까요? IOC가 무엇인지 개념이 잘 안 잡혀 있어서.. 🥹
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IOC 중 DI에 대한 이야기였습니다.
사실 의견을 여쭤본 이유가 예전 레벨 1, 2 때는 보통 객체의 필드들을 외부에서 생성해 의존성 주입을 시켜줬던 기억이 있어 저는 그렇게 진행하게 되었습니다.
그런데 여러 pr을 보다보니 저와 비슷하게 진행한 크루들도 있고 그렇지 않은 크루들도 있는 것 같아 여우의 의견도 궁금해 질문드리게 되었습니디!