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단계] 밀리(김미성) 미션 제출합니다. #630

Merged
merged 13 commits into from
Sep 27, 2023

Conversation

miseongk
Copy link

안녕하세요 케로!!

이번 단계에서는 View를 처리할 ViewResolver를 중점적으로 구현했습니다!
Legacy 코드를 최대한 변경하지 않기 위해 컨트롤러에서 String으로 반환하는 것과 ModelAndView를 반환하는 것 모두 호환되도록 구현했습니다. 제대로 했는지는 모르겠네용..

그럼 이번 단계도 잘 부탁드립니다 😊

@miseongk miseongk self-assigned this Sep 25, 2023
Copy link

@jyeost jyeost left a comment

Choose a reason for hiding this comment

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

안녕하세요 밀리!!
역시 3단계도 잘해주셨군요...!!!

몇가지 리뷰 남겼으니 확인 후 리뷰 요청 바랍니다 ><


public DispatcherServlet() {
}
private final List<ViewResolver> viewResolvers = new ArrayList<>();
Copy link

Choose a reason for hiding this comment

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

이 필드들 일급 컬렉션으로 관리하면 DispatcherServlet에서 service 메서드에 집중할 수 있을 것 같아요 !

Copy link
Author

Choose a reason for hiding this comment

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

수정했습니다! 확실히 코드가 깔끔해졌네요 ㅎㅎ

final Map<String, Object> model = modelAndView.getModel();
view.render(model, request, response);
} catch (final HandlerMappingException | ViewResolverException e) {
throw e;
Copy link

Choose a reason for hiding this comment

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

다시 예외를 던지는 것 보다
응답에 404를 내려 보내주는 것은 어떤가요?!

Copy link
Author

Choose a reason for hiding this comment

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

JspView로 404.jsp를 내려주는 것을 말씀하시는 건가요?!
그렇다면 특정 앱의 jsp 파일명을 디스패쳐 서블릿에 명시해주는 것이라서 고민이 되더라구요..!
만약 그렇게 한다면 이 디스패쳐 서블릿을 사용하는 모든 어플리케이션이 강제로 404.jsp 파일을 만들어야하기 때문에 해당 예외가 터지면 처리는 개발자에게 맡기는게 좋을 것 같다고 생각해서 그냥 예외를 던졌어요!
이 부분은 어떻게 생각하시나요??

Copy link

Choose a reason for hiding this comment

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

response에 뷰를 그려주는것이 아니라,
response.setStatus(CODE); 를 해주는 것을 의미했어요 !
지금은 커스텀 예외여도 500에러로 내려가니까용 !


final PrintWriter writer = response.getWriter();
if (model.size() == 1) {
writer.write(mapper.writeValueAsString(model.values().toArray()[0]));
Copy link

Choose a reason for hiding this comment

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

model 을 이용해서 String으로 직렬화를 해주는 로직은
따로 메서드를 분리하는 것이 어떠신가용??

@@ -16,6 +17,13 @@ public HandlerExecution(final Object handler, final Method method) {
}

public ModelAndView handle(final HttpServletRequest request, final HttpServletResponse response) throws Exception {
return (ModelAndView) method.invoke(handler, request, response);
final Object result = method.invoke(handler, request, response);
Copy link

Choose a reason for hiding this comment

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

컨트롤러에서 다양한 return값을 허용하는 거 좋네요 !!!!
널처리도 꼼꼼 하구... =bbbb

if (result == null) {
return new ModelAndView(new JsonView());
}
return new ModelAndView(result);
Copy link

Choose a reason for hiding this comment

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

그래도 더 다양한 return값이 있을수 있으니 String일 때라는 걸 명시해주면 좋을 것 같아여ㅎㅅㅎ

근데 여기서 return된 String은 view 라는 가정하에는

new ModelAndView(new JspView((String)result));

이렇게 리턴시켜주면 뷰 리졸버가 없어도 될 것 같은데.....
제가 잘못 이해한 거라면 알려주십쇼...!!

Copy link
Author

Choose a reason for hiding this comment

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

만약 JspView가 아닌 새로운 형태의 View가 생길수도 있다고 생각해서 뷰 이름만 넣어주도록 했어요.
그리고 해당 뷰 생성의 책임은 뷰 리졸버에게 넘겼어요!

다양한 return 값이 있을 수 있기 때문에 String일 때라는 것을 명시해주고, 만약 제공되지 않는 형태의 값이 들어온다면 예외를 던져주어야 겠군요!

Copy link

Choose a reason for hiding this comment

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

새로운 View가 생긴다면 ,이에 맞는 다른 View 클래스를 생성하면 되지 않을까여??
ModelAndView의 View필드가 Object이다 보니까 어떤 객체든지 들어올 수 있는 것이
추후에 예외를 초래할 수도 있을것 같다고 생각 했어요 ㅜㅜ

}

private void initHandlerMappings() {
handlerMappings.add(new WrappedManualHandlerMapping());
handlerMappings.add(new AnnotationHandlerMapping(getClass().getPackageName()));
handlerMappings.add(new AnnotationHandlerMapping());
Copy link

Choose a reason for hiding this comment

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

오... AnnotationHandlerMapping 생성할때 basePakage명을 명시해주지 않아도 되는군요...!!

DispatcherServletInitializer 클래스 기준으로 만들어 주는 걸까요???

Copy link
Author

Choose a reason for hiding this comment

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

넵 명시해주지 않아도 AnnotationHandlerMapping 내부의 초기화하는 로직에서 Reflections을 생성할 때 빈 패키지가 들어오면 해당 프로젝트의 클래스를 가져오는 것 같더라구요!

@@ -59,9 +65,11 @@ protected void service(final HttpServletRequest request, final HttpServletRespon
final Object handler = getHandler(request);
final HandlerAdapter handlerAdapter = getHandlerAdapter(handler);
final ModelAndView modelAndView = handlerAdapter.handle(handler, request, response);
final View view = modelAndView.getView();
final View view = getView(modelAndView);
Copy link

Choose a reason for hiding this comment

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

HandlerExecution 클래스 리뷰에 남긴것처럼 수정 된다면,
view resolver도 없어지고 render도 ModelAndView 내부에서 해줄 수 있을까여...??

Copy link
Author

Choose a reason for hiding this comment

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

저는 뷰 리졸버가 있는게 훨씬 확장성이 좋다고 생각해서 그대로 뒀습니다..!!

Copy link
Author

@miseongk miseongk left a comment

Choose a reason for hiding this comment

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

안녕하세요 케로!
리뷰 반영했습니다 ㅎㅎ
다시한번 확인 부탁드립니다!!


public DispatcherServlet() {
}
private final List<ViewResolver> viewResolvers = new ArrayList<>();
Copy link
Author

Choose a reason for hiding this comment

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

수정했습니다! 확실히 코드가 깔끔해졌네요 ㅎㅎ

final Map<String, Object> model = modelAndView.getModel();
view.render(model, request, response);
} catch (final HandlerMappingException | ViewResolverException e) {
throw e;
Copy link
Author

Choose a reason for hiding this comment

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

JspView로 404.jsp를 내려주는 것을 말씀하시는 건가요?!
그렇다면 특정 앱의 jsp 파일명을 디스패쳐 서블릿에 명시해주는 것이라서 고민이 되더라구요..!
만약 그렇게 한다면 이 디스패쳐 서블릿을 사용하는 모든 어플리케이션이 강제로 404.jsp 파일을 만들어야하기 때문에 해당 예외가 터지면 처리는 개발자에게 맡기는게 좋을 것 같다고 생각해서 그냥 예외를 던졌어요!
이 부분은 어떻게 생각하시나요??

if (result == null) {
return new ModelAndView(new JsonView());
}
return new ModelAndView(result);
Copy link
Author

Choose a reason for hiding this comment

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

만약 JspView가 아닌 새로운 형태의 View가 생길수도 있다고 생각해서 뷰 이름만 넣어주도록 했어요.
그리고 해당 뷰 생성의 책임은 뷰 리졸버에게 넘겼어요!

다양한 return 값이 있을 수 있기 때문에 String일 때라는 것을 명시해주고, 만약 제공되지 않는 형태의 값이 들어온다면 예외를 던져주어야 겠군요!

@@ -59,9 +65,11 @@ protected void service(final HttpServletRequest request, final HttpServletRespon
final Object handler = getHandler(request);
final HandlerAdapter handlerAdapter = getHandlerAdapter(handler);
final ModelAndView modelAndView = handlerAdapter.handle(handler, request, response);
final View view = modelAndView.getView();
final View view = getView(modelAndView);
Copy link
Author

Choose a reason for hiding this comment

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

저는 뷰 리졸버가 있는게 훨씬 확장성이 좋다고 생각해서 그대로 뒀습니다..!!

}

private void initHandlerMappings() {
handlerMappings.add(new WrappedManualHandlerMapping());
handlerMappings.add(new AnnotationHandlerMapping(getClass().getPackageName()));
handlerMappings.add(new AnnotationHandlerMapping());
Copy link
Author

Choose a reason for hiding this comment

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

넵 명시해주지 않아도 AnnotationHandlerMapping 내부의 초기화하는 로직에서 Reflections을 생성할 때 빈 패키지가 들어오면 해당 프로젝트의 클래스를 가져오는 것 같더라구요!


import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import webmvc.org.springframework.web.servlet.ModelAndView;
import webmvc.org.springframework.web.servlet.mvc.handler.HandlerExecution;
Copy link

Choose a reason for hiding this comment

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

패키지 분리 좋와용~~

Copy link

@jyeost jyeost left a comment

Choose a reason for hiding this comment

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

안녕하세요 밀리~~!!
이번 미션 너무 수고많으셨습니다!
같이 이야기하면서 저도 많이 배운것 같아서 재밌었습니다 !!
여기서 이만 머지 할게여 ><
혹시 다른 궁금한점이 있다면 디엠 주쎼용~~

@jyeost jyeost merged commit 6e9532c into woowacourse:miseongk Sep 27, 2023
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants