Dispatcher Servlet, ExceptionHandler

Dayeon myeong·2022년 3월 27일
0

면접

목록 보기
25/35

http://www.daum.net 브라우저 동작원리

  1. URL 입력
  2. URL에 해당하는 IP 주소를 DNS에서 가져옴.
  3. 해당 IP 주소를 이용하여 웹 서버와 연결
  4. http 프로토콜을 이용해 request , response로 데이터를 주고받음.
    • html 과 같은 정적 자원을 받아서 화면에 렌더링
      • 정적 자원 : url 경로와 일치하는 파일을 읽어와 항상 같은 내용을 줌.
      • 동적 자원 : url 쿼리 , 파람, 바디 와 같은 조건에 따라서 다른 응답을 보여줌. 특정 조건에 따라 응답 데이터가 달라지는 자원.
      • 동적 자원을 사용한 프로그램을 실행하기위해선 Tomcat과 같은 WAS 필요함.

WAS : Tomcat

톰캣은 동적자원을 사용한 프로그램을 사용하기 위해 필요한 서버 프로그램.

이러한 서버프로그램은 웹 을 위한 연결, 프로그래밍 언어, DB연동과 같이 어플리케이션을 구현하는데 필요한 기능을 제공한다.

WAS는 클라리언트의 요청이 오면, 요청에 따라서 알맞은 프로그램을 실행해서 동적 자원 응답을 생성

서블릿 기초

  • 자바로 웹 어플리케이션을 개발할 때 사용하는 기술
  • 서블릿은 웹 프로그래밍에서 클라이언트 HTTP 요청(request)을 받아서 처리하고, 요청에 대한 응답(response)을 클라이언트에게 전송하는 기술.
  • main() 메서드와 같은 역할을 함.
    • 독립형 앱이라면 main()메소드를 통해 프로그램을 시작. 하지만 웹에서는 main()을 호출할 방법이 없다.
    • 웹 환경에서는 서블릿 컨테이너가 브라우저로부터 오는 HTTP 요청을 받아서 해당 요청에 매핑되어있는 서블릿을 실행해준다.
    • 서블릿이 일종의 main() 메서드와 같은 역할을 함.
    • main() 메서드를 만들고, main() 메서드에서 초기화하고, 필요한 메소드나 를 실행하는 역할.
    • ex) Dispatcher Servlet : 대표 서블릿이다.
      • 애플리케이션 컨텍스트를 생성, 설정 초기화, 요청에 따라서 적절한 기능을 실행

서블릿 컨테이너

  • 서블릿 컨테이너는 브라우저와 같은 클라이언트로부터 들어오는 요청을 받아서 서블릿을 동작시켜주는 일을 맡는다.
  • 서블릿 컨테이너는 요청이 들어올때마다 새로운 자바 스레드를 만든다.
  • 서블릿 컨테이너는 servlet의 생성부터 소멸까지의 일련의 과정(Life Cycle)을 관리한다.
  • 우리가 알고 잇는 대표적인 Servlet Container가 Tomcat이다.

DispatcherServlet과 MVC 아키텍쳐

  • 스프링의 웹 기술은 MVC 아키텍쳐를 근간으로 함.

  • MVC

    • Model : 프레젠테이션 계층의 구성요소 정보를 담은 모델
    • View : 화면 로직을 담은 뷰
    • Controller : 제어로직을 담은 컨트롤러
    • 이 세거지가 서로 협력해서 하나의 웹 요청을 처리하고 응답을 만들어냄.
    • 보통 프론트 컨트롤러 패턴과 함께 사용됨
  • 프론트 컨트롤러 패턴 Front Controller

    • 중앙집중형 컨트롤러를 프레젠테이션 계층의 제일 앞에 둬서 서버로 들어오는 모든 요청을 먼저 받아서 처리하게 만든다.
      • 적절한 세부 컨트롤러로 작업을 전달, 클라이언트에게 보낼 뷰를 선택해서 최종 결과를 생성하는 작업을 함.
    • ex) DispatcherServlet
  • Dispatcher Servlet

    • 프론트 컨트롤러이다.
    • MVC 아키텍쳐로 구성된 프레젠테이션 계층을 만들 수 있도록 한다.
    • 장점 : 다양한 종류의 컨트롤러를 동시에 사용할 수 있고 많은 기능을 확장할 수 있다. 그래서 MVC 프레임워크에서 자유롭게 기능확장이 가능해서 많이 사용함.

Dispatcher Servlet 작업 흐름

  1. 서블릿 컨테이너(톰캣)를 통해 HTTP 요청을 받고, DispatcherServlet에게 HTTP 요청 전달.

  2. Handler Mapping “전략”을 사용해 특정 컨트롤러를 찾음.

    • Handler Mapping “전략” : 전략패턴, DI 적용.
      • 어떤 컨트롤러 오브젝트가 이를 처리할지 매핑해주는 전략을 만들어서 DI로 제공해주기만 하면됨. Dispatcher Servlet의 수정 없이도 DI를 통해 핸들러 매핑 전략이 확장 가능하다.
      • 스프링에서는 컨트롤러를 핸들러라고도 부른다. 즉, 컨트롤러를 웹의 요청을 handle 다루는 오브젝트라는 의미다.
      • (사실 핸들러 매핑은 핸들러 인터셉터를 적용해주는 중요한 기능도 있다)
  3. Handler Adapter “전략”을 사용해 HTTP 요청을 특정 컨트롤러에게 전달.

    • Handler Adapter도 DI를 통해 자유롭게 확장 가능하다
    • Dispatcher Servlet은 컨트롤러 호출방법을 모르기 때문에 컨트롤러 타입을 지원하는 Handler Adapter가 필요.
    • 오브젝트 어댑터 패턴 사용.
    • 특정 컨트롤러를 호출할 때 해당 컨트롤러 타입을 지원하는 어댑터를 중간에 껴서 호출. 따라서 Dispatcher Servlet은 컨트롤러가 어떤 메소드를 가져고 어떤 인터페이스를 구현했는지 전혀 알지 못하고, 어댑터가 자신이 담당하는 컨트롤러와 소통하도록 한다.
  4. 컨트롤러의 모델과 뷰 생성해서 Dispatcher Servlet에게 전달.

    • HTTP 요청을 받아서 해석하고 그에 맞는 비즈니스 로직을 서비스 계층에서 수행하고, 그 결과로 모델과 뷰를 리턴.
    • 스프링에서는 ModelAndView라는 오브젝트가 있고, 최종적으로 어댑터를 통해 컨트로러로부터 받아서 Dispatcher Servlet에게 전달.
  5. Dispatcher Servlet이 뷰를 호출하고 뷰는 모델을 참조해서 최종 결과물을 생성.

  6. DispatcherServlet은 뷰가 만들어준 최종 결과를 서블릿 컨테이너에 전달. 서블릿은 이 정보를 HTTP 응답으로 만들어 사용자의 클라이언트에게 전달.

HandlerExceptionResolver

  • DispatcherServlet에는 DI로 확장 가능한 전략이 있다. Dispatcher Servlet 코드 수정없이 확장이 가능.이러한 전략 중에 HandlerMapping, HandlerAdapter외에 HandlerExceptionResolver가 있다.

  • 예외가 발생했을 때 이를 처리하는 로직을 갖고 있다. Dispatcher Servlet은 등록된 HandlerExceptionResolver 중에서 발생한 예외에 적합한 것을 찾아서 예외처리를 위임한다.

    • ex) ResponseStausExceptionResolver 처럼 reponse로 통보

HandlerInterceptor

  • DispatcherServlet이 컨트롤러를 호출하기 전과 후에 요청과 응답을 참조하거나 가공할 수 있는 일종의 필터, HandlerInterceptor를 거쳐서 컨트롤러가 수행되거나 한다.

  • 핸들러 매핑이 이 HandlerInterceptor를 적용해준다. 핸들러 매핑은 DispatcherServlet으로 매핑 작업을 요청받으면 그 결과로 핸들러 실행 체인 HandlerExecutionChain을 돌려준다. 이 핸들러 실행 체인은 하나 이상의 핸들러 인터셉트들을 거쳐서 컨트롤러가 실행될 수 있도록 구성되어있다.

  • 장점
    • HttpServlet, HttpServletResponse, 실행될 컨트롤러 빈 오브젝트, 컨트롤러가 돌려주는 ModelAndView, 발생한 예외 등을 제공받아서 정교한 처리 작업을 할 수 있다

ExceptionHandler

@ExceptionHandler는 매우 유연하게 에러를 처리할 수 있는 방법을 제공한다. @ExceptionHandler는 다음의 경우들에 어노테이션을 추가함으로써 에러를 손쉽게 처리할 수 있다.

  • 컨트롤러의 메소드
  • @RestControllerAdvice가 붙은 클래스의 메소드

예를 들어 컨트롤러의 메소드에 @ExceptionHandler를 추가함으로써 에러를 처리할 수 있다. @ExceptionHandler에 의해 발생한 예외는 ExceptionHandlerExceptionResolver에 의해 처리가 된다.

  • 단점
    • @ExceptionHandler에 등록된 예외 클래스와 파라미터로 받는 예외 클래스가 동일해야 한다는 것이다. 만약 해당 값이 다르다면 자바나 스프링은 컴파일 시점에 에러를 내지 않다가 런타임 시점에 No suitable resolver 에러를 발생시킨다.
@ExceptionHandler(NoSuchElementFoundException.class)
public ResponseEntity<String> handleNoSuchElementFoundException(
	NoSuchElementFoundException exception) { 
    
	return ResponseEntity
    	.status(HttpStatus.NOT_FOUND)
        .body(exception.getMessage()); 
}

Controller Advice

@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으로 내려준다는 점에서 다르다.

하지만 주의점이 있다.

  • 한 프로젝트당 하나의 ControllerAdvice만 관리하며, 만약 여러 ControllerAdvice가 필요하다면 basePackages나 annotations 등을 지정한다.

스프링의 예외처리 흐름

DispatcherServlet에는 DI로 확장 가능한 전략이 있다. Handler Mapping, Handler Adapter 외에도 HandlerExceptionResolver가 있다. 이 Resolver에 의해서 예외 처리가 된다.

기본적으로는 스프링에서 BasicErrorController라는 것을 구현해두어 기본적인 에러 응답을 반환하도록 했지만
@ControllerAdvice, @ExceptionHandler 가 있는지 검사하여 해당 @ExceptionHandler가 발생한 예외를 처리할 수 있다면 에러 응답을 제공한다.

참고

토비의 스프링

JSP 2.3 웹 프로그래밍

https://mangkyu.tistory.com/204

[Servlet] 서블릿 컨테이너와 스프링 컨테이너

[10분 테코톡] 🌻타미의 Servlet vs Spring

profile
부족함을 당당히 마주하는 용기

0개의 댓글