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

[이호석] 스프링 부트의 Whitelabel Error Page 생성 전 과정 살펴보기! #6

Open
HiiWee opened this issue Apr 7, 2023 · 0 comments
Assignees
Labels

Comments

@HiiWee
Copy link
Member

HiiWee commented Apr 7, 2023

🤔 왜 이슈를 생성했나요?

재홍님의 #1 이슈에 대한 답변 이슈이자, 공유하고 싶은 내용이어서 조금 길지만 작성해봅니다!
(스크린샷이 잘 보이지 않아서 화면을 확대해서 보길 권장합니다!)



😁 공유하고 싶은 내용

테스트용 Controller
존재하지 않는 viewName을 반환한다.
image


DispatcherServlet은 가장먼저 “/”로 들어온 요청에 대해 처리를 시작합니다. 이때 요청 URI는 “/”가 되고, DispatcherType은 “REQUEST”가 됩니다.
image


TestController의 test()메소드가 해당 URI와 매핑되어있으므로 해당 컨트롤러를 실행하고 반환값으로 “dd”라는 viewName을 받게 됩니다.
해당 정보를 가지고 ModelAndView를 생성하고 내부 View 정보를 통해 RequestDispatcher가 forwarding 작업을 합니다.
image


포워딩 됐으므로 dispatcherType은 FORWARD이며, “/dd” 라는 리소스를 DispatcherServlet이 내부적으로 호출하게 됩니다.
다시 DispatcherServlet을 통해 내부적인 doService() → doDispatch 작업을 수행하게 됩니다.
image


DispatcherServlet.doDispatch()에서 HandlerAdapter를 찾아 handle()하게 되는데 이는 어댑터(HttpRequestHandlerAdapter)를 통해 찾아온 핸들러를 실행시키게 됩니다.
image
image


이때 정적 리소스를 처리하는 ResourceHttpRequestHandler가 선택되고 “/dd”에 대한 실제 리소스를 가져오지만 존재하지 않으므로 null값이 반환됩니다.
resource가 null이므로 Not Found 에러를 Response 객체에 세팅합니다. 이때 sendError내부 코드에서 setError를 통해 0 → 1로 에러 플래그를 세팅합니다.
image
image
image


사용자의 “/” 요청이 마무리되고 WAS까지 404 Error가 전파됩니다. 그리고 Tomcat에서 에러가 존재하는지 묻게 됩니다.
이때 아까 setError를 통해 1로 세팅한 에러값을 통해 에러가 있음을 WAS가 인지하게 됩니다.
image


이후 404 Not Found에 대한 에러 페이지를 찾게 됩니다. 따로 생성한 에러페이지는 존재하지 않으므로 WAS에서 생성하는 디폴트 에러 페이지를 찾게 됩니다.
image


/error 로케이션을 받아오고 이후 각종 에러에 대한 세팅을 해줍니다(DispatcherType을 ERROR 세팅 등)
이후 /error에 대해 WAS 내부에서 포워딩 작업을 실행합니다.
image
image


포워딩 작업이 시작됐으므로 다시 필터를 거치고 DispatcherServlet을 호출하게 됩니다.
image


“/error”로 requestURI가 선택되어 있는데 해당 uri는 BasicErrorController@RequestMapping과 일치합니다.

또한 Accept headertext/html이므로 BasicErrorController#errorHtml 핸들러 메소드가 선택됩니다.
RequestMappingHandlerAdapter는 이런 @RequestMapping이 되어있는 핸들러를 지원하므로(HandlerAdapter#supports를 지원함) 어댑터로 선택됩니다.
image
image
image
(이 이미지는 좌측 하단의 main 쓰레드내 메소드 스택을 통해 흐름을 이해하기 편하도록 첨부했습니다.)


이후 실제 BasicErrorController#errorHtml을 실행한다.
image


errorHtml의 내부 호출 메소드인 resolveErrorView에서는DefaultErrorViewResolver#resolveErrorView를 호출해 에러페이지에 대한 view resolving 수행합니다.
image


DefaultErrorViewResolver#resoveErrorView 에서는 두번째 사진의 staticLocations과 같은 순서로 view를 찾는다.
하지만 일치하는 View가 없으므로 null을 반환하게 된다. BasicErrrorController#errorHtml에서는 반환된 ModelAndView 객체가 null값이라면 “error”라는 viewName을 가진 ModelAndView 객체를 생성해 반환한다.
image
image


반환된 ModelAndView 객체를 처리하가 위해 ModelAndView 응답 value를 처리하는 핸들러로 ModelAndViewMethodReturnValueHandler가 선택된다.
이곳에서 뷰 이름 세팅, 응답 코드 세팅 , 리다이렉트에 대한 처리 등을 수행한다.
image


이후 BasicErrorController#errorHtml을 통해 생성된 ModelAndView 객체가 DispatcherServlet으로 반환된다.
받아온 ModelAndView 객체 내부의 View를 reolving하는데 이때 ContentNegotiatingViewReolver가 선택된다.
image


ContentNegotiatingViewResolver#resolveViewName 에서는 getCandiateViews()를 통해 후보가 될 수 있는 View를 선택하고 이후 getBestView()를 통해 최적의 View를 선택한다.

후보군 View로는 ErrorMvcAutoConfiguration$StaticView와 정적 리소스를 처리하는 InternalResourceView 2개가 선택된다.
image


best view로는 ErrorMvcAutoConfiguration$StaticView가 더 높은 우선순위를 가지고 있고, text/html에 대해 ErrorMvcAutoConfiguration$StaticView가 처리할 수 있으므로 즉시 해당 뷰를 반환한다.
image


이후 DispatcherServlet은 받아온 ErrorMvcAutoConfiguration$StaticView를 통해 뷰 렌더링을 진행한다.
실제 StaticView의 render 메소드를 살펴보면 우리가 익히 볼 수 있는 Whitelabel Error Page를 볼 수 있다. 여기서 이전에 정해진 error 내용과 status code를 결합해 응답 HTML을 완성한다.
image


이후 응답 처리를 마치고 브라우저에는 404 Whitelabel Error Page가 응답된다.
image



📌 참고자료

  • Springframwork 내부 코드
@HiiWee HiiWee added the 공유 label Apr 7, 2023
@HiiWee HiiWee self-assigned this Apr 7, 2023
@HiiWee HiiWee changed the title [이호석] 스프링 부트의 White Label Error page 생성 전 과정 살펴보기! [이호석] 스프링 부트의 White Label Error page 생성 전 과정 살펴보기! (#1 이슈 답글) Apr 7, 2023
@HiiWee HiiWee changed the title [이호석] 스프링 부트의 White Label Error page 생성 전 과정 살펴보기! (#1 이슈 답글) [이호석] 스프링 부트의 White Label Error page 생성 전 과정 살펴보기! Apr 7, 2023
@HiiWee HiiWee changed the title [이호석] 스프링 부트의 White Label Error page 생성 전 과정 살펴보기! [이호석] 스프링 부트의 Whitelabel Error Page 생성 전 과정 살펴보기! Apr 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant