개발영어공부

[Spring 공식문서 번역 프로젝트]Spring Web MVC (1.1.5 ~1.1.8)

robinjoon98 2022. 5. 8. 19:37

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;
    }
}