톰캣은 동적자원을 사용한 프로그램을 사용하기 위해 필요한 서버 프로그램.
이러한 서버프로그램은 웹 을 위한 연결, 프로그래밍 언어, DB연동과 같이 어플리케이션을 구현하는데 필요한 기능을 제공한다.
WAS는 클라리언트의 요청이 오면, 요청에 따라서 알맞은 프로그램을 실행해서 동적 자원 응답을 생성
스프링의 웹 기술은 MVC 아키텍쳐를 근간으로 함.
MVC
프론트 컨트롤러 패턴 Front Controller
Dispatcher Servlet
서블릿 컨테이너(톰캣)를 통해 HTTP 요청을 받고, DispatcherServlet에게 HTTP 요청 전달.
Handler Mapping “전략”을 사용해 특정 컨트롤러를 찾음.
Handler Adapter “전략”을 사용해 HTTP 요청을 특정 컨트롤러에게 전달.
컨트롤러의 모델과 뷰 생성해서 Dispatcher Servlet에게 전달.
Dispatcher Servlet이 뷰를 호출하고 뷰는 모델을 참조해서 최종 결과물을 생성.
DispatcherServlet은 뷰가 만들어준 최종 결과를 서블릿 컨테이너에 전달. 서블릿은 이 정보를 HTTP 응답으로 만들어 사용자의 클라이언트에게 전달.
DispatcherServlet에는 DI로 확장 가능한 전략이 있다. Dispatcher Servlet 코드 수정없이 확장이 가능.이러한 전략 중에 HandlerMapping, HandlerAdapter외에 HandlerExceptionResolver가 있다.
예외가 발생했을 때 이를 처리하는 로직을 갖고 있다. Dispatcher Servlet은 등록된 HandlerExceptionResolver 중에서 발생한 예외에 적합한 것을 찾아서 예외처리를 위임한다.
DispatcherServlet이 컨트롤러를 호출하기 전과 후에 요청과 응답을 참조하거나 가공할 수 있는 일종의 필터, HandlerInterceptor를 거쳐서 컨트롤러가 수행되거나 한다.
핸들러 매핑이 이 HandlerInterceptor를 적용해준다. 핸들러 매핑은 DispatcherServlet으로 매핑 작업을 요청받으면 그 결과로 핸들러 실행 체인 HandlerExecutionChain을 돌려준다. 이 핸들러 실행 체인은 하나 이상의 핸들러 인터셉트들을 거쳐서 컨트롤러가 실행될 수 있도록 구성되어있다.
@ExceptionHandler는 매우 유연하게 에러를 처리할 수 있는 방법을 제공한다. @ExceptionHandler는 다음의 경우들에 어노테이션을 추가함으로써 에러를 손쉽게 처리할 수 있다.
예를 들어 컨트롤러의 메소드에 @ExceptionHandler를 추가함으로써 에러를 처리할 수 있다. @ExceptionHandler에 의해 발생한 예외는 ExceptionHandlerExceptionResolver에 의해 처리가 된다.
@ExceptionHandler(NoSuchElementFoundException.class)
public ResponseEntity<String> handleNoSuchElementFoundException(
NoSuchElementFoundException exception) {
return ResponseEntity
.status(HttpStatus.NOT_FOUND)
.body(exception.getMessage());
}
@ExceptionHandler는 특정 컨트롤러의 예외를 처리하는데 좋지만 @ExceptionHandler가 구현된 컨트롤러에서만 예외가 처리되므로 다른 컨트롤러에도 에러 처리 코드가 중복될 가능성이 매우 높다.
Spring은 @ExceptionHandler의 한계를 극복하고자 전역적으로 예외를 처리할 수 있는 @ControllerAdvice와 @RestControllerAdvice 어노테이션을 각각 Spring3.2, Spring4.3부터 제공하고 있다. 즉, ControllerAdvice는 여러 컨트럴러에 대해 전역적으로 ExceptionHandler를 적용하도록 한다.
ContollerAdvice의 'Advice'라는 용어는 AOP(Aspect-Oriented Programming)에서 따온 것으로, 기존 메서드 주위에 교차 절단 코드를 주입하는 AOP의 방식을 활용해 예외를 처리한다는 점에서 이름을 따왔다.
@ControllerAdvice는 text/plain으로 응답을 제공하는 반면 @RestControllerAdvice는 @ControllerAdvice에 @ResponseBody가 붙어 있어 응답을 Json으로 내려준다는 점에서 다르다.
하지만 주의점이 있다.
DispatcherServlet에는 DI로 확장 가능한 전략이 있다. Handler Mapping, Handler Adapter 외에도 HandlerExceptionResolver가 있다. 이 Resolver에 의해서 예외 처리가 된다.
기본적으로는 스프링에서 BasicErrorController라는 것을 구현해두어 기본적인 에러 응답을 반환하도록 했지만
@ControllerAdvice, @ExceptionHandler 가 있는지 검사하여 해당 @ExceptionHandler가 발생한 예외를 처리할 수 있다면 에러 응답을 제공한다.
토비의 스프링
JSP 2.3 웹 프로그래밍