본문 바로가기

IT/Spring

[SpringBoot] HandlerInterceptor 설정하기

1. HandlerInterceptor 란?

Spring Framework에서 지원하는 기능이며, URI 요청, 응답 시점을 가로채서 전/후 처리를 하는 역할을 합니다. Interceptor 시점에 Spring ContextBean에 접근할 수 있습니다. 

이와 비슷한 역할로 Filter와 AOP가 있습니다.

Filter는 Spring Framework와 무관하게 동작하며, Spring 자원을 이용할 수 없습니다. Filter는 보통 인코딩, XSS방어 등...의 용도로 이용됩니다. 

AOP는 주로 비즈니스 로직에서 실행됩니다. Logging, transaction 처리 등 중복 코드가 발생할 경우 중복을 줄이기 위해 사용되며, 메소드 처리 전후 지점에 자유롭게 설정이 가능합니다.  

2. Filter, Interceptor, AOP의 흐름

https://goddaehee.tistory.com/154

3. Interceptor 생성

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class MyInterceptor implements HandlerInterceptor {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public boolean preHandle(
            HttpServletRequest request,
            HttpServletResponse response,
            Object handler
    ) throws Exception {
        logger.info("[MYTEST] preHandle");
        return true;
    }

    @Override
    public void postHandle(
            HttpServletRequest request,
            HttpServletResponse response,
            Object handler,
            ModelAndView modelAndView
    ) throws Exception {
        logger.info("[MYTEST] postHandle");
    }

    @Override
    public void afterCompletion(
            HttpServletRequest request,
            HttpServletResponse response,
            Object object,
            Exception ex
    ) throws Exception {
        logger.info("[MYTEST] afterCompletion");
    }
}

1) PreHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
컨트롤러에 진입하기 전에 실행됩니다. 반환 값이 true일 경우 컨트롤러로 진입하고 false일 경우 진입하지 않습니다.
Object handler는 진입하려는 컨트롤러의 클래스 객체가 담겨있습니다.

2)PostHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
컨트롤러 진입 후  View가 랜더링 되기 전에 수행됩니다.

3) afterComplete(HttpServletRequest request, HttpServletResponse response, Object object, Exception ex)
컨트롤러 진입 후 view가 랜더링 된 후에 실행되는 메소드입니다.

 4) afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object h)
비동기 요청 시 PostHandle과 afterCompletion이 수행되지 않고 afterConcurrentHandlingStarted가 수행됩니다. 

4. Interceptor 등록하기

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor())
                .addPathPatterns("/*") // 해당 경로에 접근하기 전에 인터셉터가 가로챈다.
                .excludePathPatterns("/boards"); // 해당 경로는 인터셉터가 가로채지 않는다.
    }
}

WebMvcConfigurer를 구현해 Spring Boot에서 기본적으로 제공해주는 설정 중 interceptor부분을 커스텀합니다.

5. HomeController

@Controller
@RequestMapping("/")
public class HomeController {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @GetMapping("/users")
    public String users() {
        logger.info("[MYTEST] users!!");
        return "생략..";
    }

    @GetMapping("/boards")
    public String boards() {
        logger.info("[MYTEST] boards!!");
        return "생략..";
    }
}

6. Test

GET localhost:8080/bamdule/users 요청

[MYTEST] preHandle
[MYTEST] users!!
[MYTEST] postHandle
[MYTEST] afterCompletion

GET localhost:8080/bamdule/boards 요청

[MYTEST] boards!!

참조 : https://goddaehee.tistory.com/154