doDispatch, doService 코드를 보고 나머지 코드들을 보려니까 마음이 편하다.
render메서드와 resolveViewName, applyDefaultViewName 메서드는 모두 view와 관련한 코드들로 handler로부터 받은 값을 처리해주는 역할을 한다.
Render
render 메서드의 동작은 다음과 같다.
1. Locale 설정
2. View 객체 가져오기
3. ModelAndView의 View 객체 사용
4. 응답 상태 설정 및 렌더링
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
// ModelAndView 객체에서 locale을 가져오고, localeResolver가 null이 아닐 경우 localeResolver로부터 Locale 객체를 가져옴
Locale locale = this.localeResolver != null ? this.localeResolver.resolveLocale(request) : request.getLocale();
response.setLocale(locale); // 가져온 locale을 응답값에 설정
/**
* view 이름 설정
*/
String viewName = mv.getViewName();
View view;
if (viewName != null) {
// view 이름이 존재하면 resolveViewName을 통해 View 객체 생성
view = this.resolveViewName(viewName, mv.getModelInternal(), locale, request);
if (view == null) {
// view 이름을 가져오지 못하는 경우 예외를 발생
String var10002 = mv.getViewName();
throw new ServletException("Could not resolve view with name '" + var10002 + "' in servlet with name '" + this.getServletName() + "'");
}
} else {
view = mv.getView(); // View 이름이 존재하지 않을 경우 ModelAndView 객체의 View 객체를 가져옴
if (view == null) {
// View 객체가 존재하지 않을 경우 예외를 발생시킴
throw new ServletException("ModelAndView [" + mv + "] neither contains a view name nor a View object in servlet with name '" + this.getServletName() + "'");
}
}
if (this.logger.isTraceEnabled()) {
this.logger.trace("Rendering view [" + view + "] ");
}
try {
// ModelAndView 객체에 HTTP 응답 상태가 설정되어 있다면 해당 상태를 request에 설정하고 response의 상태를 설정
if (mv.getStatus() != null) {
request.setAttribute(View.RESPONSE_STATUS_ATTRIBUTE, mv.getStatus());
response.setStatus(mv.getStatus().value());
}
// View의 render() 메서드를 호출하여 최종적으로 Model 데이터를 View와 함께 response로 렌더링
view.render(mv.getModelInternal(), request, response);
} catch (Exception var8) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Error rendering view [" + view + "]", var8);
}
throw var8;
}
}
ViewResolve
viewResolveName 함수는 viewResolvers를 순회하면서 View 객체를 찾아 반환하는 역할을 한다
@Nullable
protected View resolveViewName(String viewName, @Nullable Map<String, Object> model, Locale locale, HttpServletRequest request) throws Exception {
// viewResolvers가 null이 아닐 경우, ViewResolver 리스트에서 View 객체를 찾음
if (this.viewResolvers != null) {
// viewResolvers 리스트를 순회할 Iterator 객체 생성
Iterator var5 = this.viewResolvers.iterator();
// 모든 ViewResolver를 순회하며 viewName에 맞는 View 객체를 찾음
while (var5.hasNext()) {
// 현재 순회 중인 ViewResolver 객체를 가져옴
ViewResolver viewResolver = (ViewResolver) var5.next();
// viewName과 locale을 기준으로 ViewResolver에게 View 객체를 요청
View view = viewResolver.resolveViewName(viewName, locale);
// ViewResolver가 유효한 View 객체를 반환한 경우, 해당 View 객체를 반환
if (view != null) {
return view;
}
}
}
// 모든 ViewResolver가 null을 반환한 경우 null을 반환하여 View를 찾지 못했음을 알림
return null;
}
applyDefaultViewName
doDispatch에서 ModelAndView를 받아서 기본 View이름을 적용해주는 메서드
private void applyDefaultViewName(HttpServletRequest request, @Nullable ModelAndView mv) throws Exception {
// ModelAndView 객체가 null이 아니고, View가 설정되어 있지 않은 경우에만 기본 View 이름을 적용
if (mv != null && !mv.hasView()) {
// HttpServletRequest 객체로부터 기본 View 이름을 가져옴
String defaultViewName = this.getDefaultViewName(request);
// 기본 View 이름이 존재할 경우, ModelAndView 객체에 View 이름을 설정
if (defaultViewName != null) {
mv.setViewName(defaultViewName);
}
}
}
'Web > Spring' 카테고리의 다른 글
[Spring Web 6.1] DispatcherServlet 뜯어보기 - SSR 렌더링 과정 (0) | 2024.10.07 |
---|---|
[Spring Web 6.1] DispatcherServlet 뜯어보기 - Multipart & ExceptionHandling (1) | 2024.10.07 |
[Spring Web 6.1] DispatcherServlet 뜯어보기 - dispatch (0) | 2024.10.07 |
[Spring Web 6.1] DispatcherServlet 뜯어보기 - getter & setter (0) | 2024.10.04 |
[Spring Web 6.1] DispatcherServlet 뜯어보기 - Constructor & init (0) | 2024.10.04 |