HandlerExceptionResolver1.1.5 프로세싱
DispatcherServlet은 아래와 같은 순서대로 요청을 처리한다.
- 프로세스중에 컨트롤러나 다른 요소가 사용할 수 있는 속성인 WebApplicationContext 은 요청에서 검색되고 바인드됩니다. 기본적으로 DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE 키 아래에 바인딩된다.
- 요청을 처리할 때(View를 렌더링 하거나, 데이터를 준비하는 등의), 요청처리(process)의 각 요소가 locale을 해결할 수 있도록 locale resolver 는 요청에 바인드된다. 만일 locale 처리가 필요없다면 locale resolver는 필요 없다.
- theme resolver 는 view 등의 요소가 사용할 테마를 결정하기 위해 효청에 바인드 된다. 만일 theme를 사용하지 않는다면 무시해도 된다.
- 만약 multipart file resolver 를 지정한다면, 요청에 multipart가 있는지 검사된다. 만약 multiparts가 발견된다면, 요청은 다른 요소에 의해 추가작업이 이루어지도록 MultipartHttpServletRequest로 감싸진다. 자세한 사항은 Multipart Resolver 를 참고해라
- 적절한 핸들러를 검색한다. 만일 핸들러가 발견되면 렌더링을 위한 모델을 준비하기 위해 핸들러와 연관된 실행체인(preprocessors, postprocessors, and controllers)이 실행된다. 그 대신에 어노테이션이 달린 컨트롤러의 경우 응답은 뷰를 반환하는 것 대신에 HandlerAdapter 내에서 랜더링 될 수도 있다.
- 모델이 반환되면 뷰가 렌더링된다. 만약 모델이 반환되지 않으면( 보안상의 이유로 preprocessor 나 postprocessor가 요청을 인터셉트하는 경우 등) 뷰는 렌더링되지 않는다. 요청이 이미 이행되었을 수 있기 때문이다.

- 디스패처 서블릿 : 모든 요청을 받음. 요청을 분석하고 처리하기 위해 적절한 컨트롤러로 요청전달(기능 위임)
- 공통 서비스 : 모든 요청에 제공 (Servlet WebApplicationContext에 정의)
로케일 해석, 테마 해석, 멀티파트(파일 업로드) 핸들링 - 핸들러 맵핑 : HTTP 요청정보를 이용해 핸들러(컨트롤러 클래스 내 메서드)에 맵핑한다.
- lookupHandlerMethod()에서 수행
- urlLookup이라는 Map에 url 매핑정보 존재
- @RequestMapping(@GetMapping 등..)을 적용 → Http경로와 핸들러를 매핑한 구현체를 자동으로 등록 (직접 구성할 필요X)
- 핸들러 인터셉터 : DispatcherServlet이 컨트롤러를 호출하기 전과 후에 요청, 응답을 가공하는 일종의 필터
- 핸들러 어댑터 : 결정된 Controller의 메소드를 호출하는 역할
- DispatcherServlet이 Handlerㅏ 어떤 방식으로 구현되어 있는지 신경쓰지 않게 해줌
- 핸들러 익셉션 리졸버(Handler Exception Resolver) : 핸들러의 요청처리 중 발생하는 예외를 처리
- View Resolver : 어떤 종류의 view(JSP, html 등)를 사용할 것인지 선택하고 문자열을 기반으로 사용할 view를 선택하는 역할
- 컨트롤러가 반환한 논리적이름을 기반으로 뷰를 해석해 찾아냄
- 다양한 메커니즘을 지원하는 구현 클래스 존재
- 선택된 view는 저장된 Model의 데이터를 이용해 페이지를 완성하고 사용자에게 응답
1.1.6. 경로 매칭 > 내용이 이해 안가서 생략
1.1.7. 인터셉트
모든 HandlerMapping의 구현체는 특정 요청에 특정 기능을 적용하는데 유용한 핸들러 인터셉터(handler interceptors)를 지원합니다. 예를 들어 보안 기능을 구현할 때 유용합니다. 인터셉터는 org.springframework.web.servlet 패키지의 HandlerInterceptor 인터페이스를 구현해야 합니다. 이 인터페이스는 아래 3가지의 메서드를 가지고 있고 이 메서드들은 모든 종류의 전처리와 후처리를 제공하기 위해 충분한 확장성을 제공해야합니다.
- preHandle(..): 실제 핸들러가 실행되기 전
- postHandle(..): 실제 핸들러가 실행된 후
- afterCompletion(..): 요청 전체가 완전히 끝난 후
preHandle(..) 메서드는 boolean 값을 반환합니다. 이 메서드를 요청 처리를 위한 실행 체인을 계속하거나 중지하기 위해 사용할 수 있습니다. 메서드가 true 를 반환한다면 핸들러의 실행 체인은 계속되고, false를 반환하면 DispatcherServlet 은 인터셉터 자체가 그 요청을 돌본다고 가정합니다(예를 들어 적절한 뷰를 렌더링한다던지). 그리고 더이상 다른 인터셉터나 핸들러의 실행 체인을 실행하지 않습니다.
Interceptors 를 보면 인터셉터를 어떻게 설정하는지 예시가 나와있습니다. 또한, 개별 HandlerMapping 구현체에서 setter 를 이용해 직접 인터셉터를 등록할 수도 있습니다.
postHandle 은 @ResponseBody 와 ResponseEntity 를 사용하는 핸들러 메서드의 경우에선 그 효용성이 떨어진다. 이들의 경우 postHandle 이 실행되기 전에 응답이 커밋되고 쓰여지기 때문이다. 이는 응답에 헤더를 추가하는 등 어떤 변경을 주기에는 너무 늦었다는 말이다. 이런 시나리오에서는 ResponseBodyAdvice 를 구현하고 Controller Advice 빈으로 정의하거나, RequestMappingHandlerAdapter 에서 직접 설정할 수 있다.
1.1.8. 예외
요청을 매핑하는 도중이나 요청핸들러(@Controller과 같은)에서 예외가 발생하는 경우 DispatcherServlet 는 실행 흐름을 HandlerExceptionResolver 빈에 위임하여 예외 해결과 대안(일반적으로 오류 응답)을 제공하도록 합니다.아래 표는 HandlerExceptionResolver 의 구현체 목록 입니다.
| HandlerExceptionResolver | 설명 |
| SimpleMappingExceptionResolver | 예외 클래스 이름과 예외 뷰 이름을 매핑합니다. 브라우저 애플리케이션에서 에러 페이지를 렌더링하는데 유용합니다. |
| DefaultHandlerExceptionResolver | 스프링 MVC 에 의해 제기된 예외를 해결하고 이를 HTTP 상태코드와 매핑합니다. ResponseEntityExceptionHandler 와 REST API exceptions 를 참고하세요. |
| ResponseStatusExceptionResolver | @ResponseStatus 어노테이션이 붙은 예외를 처리하고 이를 어노테이션의 값을 이용해 HTTP 상태코드와 매핑합니다. |
| ExceptionHandlerExceptionResolver | @Controller 또는 @ControllerAdvice 클래스에서 @ExceptionHandler 메서드를 호출하여 예외를 해결합니다. @ExceptionHandler 메소드를 참조하십시오. |
예외처리 체인
스프링 설정에서 여러 HandlerExceptionResolver 빈을 등록하고 필요하면 순서 속성을 지정하여 예외처리 체인을 구성할 수 있습니다. 높은 순서 옵션이 높을 수록 예외 처리기가 나중에 배치됩니다.
HandlerExceptionResolver 의 일반 규약에선 다음을 반환할 수 있도록 합니다.
- 에러 뷰를 가지는 ModelAndView
- 비어있는 ModelAndView : 예외가 말끔히 처리된 경우
- 예외가 처리되지 않고 남아있는 경우 null을 반환하고, 후속 HandlerExceptionResolver 가 예외처리를 시도하도록 합니다. 모든 HandlerExceptionResolver가 처리를 시도한 후에도 예외가 남아있는 경우 서블릿 컨테이너까지 전달이 허용됩니다.
MVC Config 가 Spring MVC 기본 예외를 위해 내장된 예외처리기를 자동으로 등록합니다. 예외 리스트를 커스텀할 수 있습니다.
컨테이너 에러 페이지
모든 HandlerExceptionResolver가 실행된 후 예외가 남아있거나, 오류 상태(4XX, 5XX)로 지정된 경우 서블릿 컨테이너가 기본 에러 페이지를 HTML로 렌더링 합니다. 컨테이너의 기본 에러 페이지를 커스텀하기 위해선 web.xml에 에러 페이지를 정의해야 합니다. 아래 예시가 있습니다.
<error-page>
<location>/error</location>
</error-page>
예외가 발생된 경우 그 예외를 적절한 형태로 응답하는 Controller를 추가할 수 있습니다. 아래 예시가 있습니다.
@RestController
public class ErrorController {
@RequestMapping(path = "/error")
public Map<String, Object> handle(HttpServletRequest request) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("status", request.getAttribute("javax.servlet.error.status_code"));
map.put("reason", request.getAttribute("javax.servlet.error.message"));
return map;
}
}
'개발영어공부' 카테고리의 다른 글
| [Spring 공식문서 번역 프로젝트]Spring Web MVC (1.1.9) (0) | 2022.05.22 |
|---|---|
| [Spring 공식문서 번역 프로젝트] Spring Web MVC (~1.1.4) (0) | 2022.04.07 |
| [JVM 공식문서 번역프로젝트] 1. Introduction (0) | 2022.03.29 |