📝 인터셉터란?
- 인터셉터(Interceptor)는
DispatcherServlet
과 컨트롤러(Controller
) 사이에서 요청(request
)을 가로채는 역할을 수행합니다. - 인터셉터를 사용하면 기존의 로직을 수정하지 않고 비즈니스 로직 전후에서 특정 기능을 수행할 수 있습니다.
- 인터셉터를 구현하기 위해서는
HandlerInterceptor
를 사용합니다.
📝 HandlerInterceptor 구조
HandlerInterceptor
의 전체적인 요청과 응답의 흐름은 아래 그림과 같습니다.
- 먼저 요청(
Request
)이 들어오게 되면Filter
를 거친 후에DispatcherServlet
으로 오게됩니다. - 이후
DispatcherServlet
에서는HandlerMapping
을 거쳐 어떤Handler
(Controller
)로 가야할 지 결정하게 됩니다. - 다음으로
Handler
로 가게되는 시점에 먼저HandlerInterceptor
가 동작하게 되고, 이후Handler
에 도착하면 우리가 작성한 비즈니스 로직을 수행하게 됩니다. - 이후
Handler
는 응답값을 만들어HandlerInterceptor
에게 제공하고,HandlerInterceptor
에서는 해당 값을 전달받음으로서 전후로 동작할 수 있게 되는 구조입니다. - 그 이후에는
View
가 있다면ViewResolver
와View
를 거치고, 다시DispatcherServlet
과Filter
를 통해서 응답(Response
)이 나가게 됩니다.
Filter와 HandlerInterceptor는 요청이 가는 도중에 이를 가로채서 특정 로직을 수행한다는 뜻에서 그 역할은 비슷하지만 Filter의 경우 스프링 컨텍스트 바깥에 존재하기 때문에 스프링 컴포넌트에 접근하기가 어려우며, HandlerInterceptor의 경우 스프링 컨텍스트 안에 존재하기 때문에 스프링 컴포넌트에 접근이 용이하다라는 차이가 있습니다.
📝 HandlerInterceptor 인터페이스
HandlerInterceptor
의 코드 구조는 아래와 같으며, 보시는 바와 같이 3개의 메소드가 정의되어 있습니다.- 각 메소드에는
default
키워드가 붙어있는 것을 확인할 수 있는데, 이는 인터페이스를 구현할 때 해당 메소드를 의무적으로 구현해줄 필요가 없다는 의미입니다. 즉, 필요한 메소드만 오버라이딩(overriding
)하여 구현할 수 있도록 편의성을 제공해주는 역할이라고 이해할 수 있습니다. - 각 메소드의 매개변수로 전달되고 있는
handler
객체는 요청을 전달할 컨트롤러 객체를 의미합니다.
preHandle()
- 컨트롤러로 요청이 가기 전에 수행할 코드를 작성하는 메소드
- 리턴 타입이
boolean
형이며 리턴값이true
일 경우 컨트롤러로 요청을 전달하고false
일 경우 전달하지 않는다.
postHandle()
- 컨트롤러의 로직이 수행된 이후
View
가 렌더링 되기 전에 수행할 코드를 작성하는 메소드 - 매개변수로
ModelAndView
객체를 전달받고 있으며 이를 통해View
에 렌더링 시킬 객체를 추가할 수 있다.
- 컨트롤러의 로직이 수행된 이후
afterCompletion()
View
가 렌더링 된 후에 실행되는 메소드- 매개변수로
Exception
객체를 전달받고 있으며 비즈니스 로직에서 예외가 발생했을 경우 이를 통해 처리할 수 있다.
WAS가 요청을 받으면 HttpServletRequest와 HttpServletResponse 객체를 생성하여 웹 애플리케이션으로 전달합니다.
HttpServletRequest는 Http 프로토콜의 Request 정보를 서블릿으로 전달하기 위해 사용되는 객체로서, Header, Parameter, Cookie, URL, URI 등의 정보를 가지게 됩니다. 또한 Body의 값을 읽기 위한 메소드를 가지고 있습니다.
HttpServletResponse는 요청에 대한 응답값을 담기 위한 객체로서, Content-Type이나 응답 코드, 메시지를 가지게 됩니다.
📝 인터셉터 사용하기
- 다음으로 인터셉터를 설정하여 프로젝트에 적용하는 과정에 대해 알아보도록 하겠습니다.
📜 의존성 추가
- 인터셉터를 이용하기 위해서는 우선 아래와 같이 의존성을 추가해주어야 합니다.
Maven
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Gradle
compile('org.springframework.boot:spring-boot-starter-web')
📜 HandlerInterceptor 인터페이스 구현체 작성
- 다음으로
HandlerInterceptor
인터페이스를 구현하는 구현체를 작성해줍니다.
@Component
public class HttpInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
// 로직 작성
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView) throws Exception {
// 로직 작성
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception exception) throws Exception {
// 로직 작성
}
}
📜 WebMvcConfigurer 구현체 작성
- 마지막으로
WebMvcConfigurer
를 구현하는 구현체에서addInterceptors()
메소드를 오버라이딩하여 우리가 생성한 인터셉터를 등록해주면 됩니다.
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new HttpInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/hello");
}
}
addPathPatterns()
: 해당 인터셉터가 동작할 경로를 설정하는 메소드excludePathPatterns()
: 해당 인터셉터에 대한 동작을 예외시킬 경로를 설정하는 메소드
'🥑 Web Technoloy' 카테고리의 다른 글
Lombok이란? (1) | 2023.06.04 |
---|---|
Spring AOP(Aspect Oriented Programming) (0) | 2023.06.03 |
SpringBoot에서 SMTP를 활용한 메일 전송 구현하기 (0) | 2022.11.16 |
OAuth 2.0 개념 정리 (0) | 2022.11.11 |
스프링 부트 Spring Security (0) | 2022.11.10 |