본문 바로가기
🖥Web/🔥SpringBoot

[SpringBoot] Interceptor(인터셉터) HandlerInterceptor로 간단히 intercept하기

by 후누스 토르발즈 2021. 1. 13.
반응형

 

 

 

 

 

HandlerInterceptor : 세션이나 쿠키, 검증 등을 위하여 사용한다.

일반적인 요청흐름이 흐르기전에 controller 전에 가로채서 처리한다.

 

 

Servlet Filter와 HandlerInterceptor의 차이

 

 

Filter와 Interceptor 비교

필터는 DispatcherServlet 앞에서 먼저 동작하고, 인터셉터는 DispatcherServlet에서 Controller(Handler) 사이에서 동작한다.

 

필터

  • 웹 어플리케이션의 Context의 기능

  • 스프링 기능을 활용하기에 어려움

  • 일반적으로 인코딩, CORS, XSS, LOG, 인증, 권한 등 을 구현

 

인터셉터

  • 스프링의 Spring Context의 기능이며 일종의 빈

  • 스프링 컨테이너이기에 다른 빈을 주입하여 활용성이 좋음

  • 다른 빈을 활용 가능하기에 인증, 권한 등을 구현함

 

 

 

 

 

핸들러 오버라이딩하는 부분

 

AccessInterceptor.java

package com.example.base.common.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class AccessInterceptor implements HandlerInterceptor {

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		log.debug("AccessInterceptor preHandle() :: ");
		log.debug("request.getRequestURI() : " + request.getRequestURI());
		//TODO
		//Access Intercept
		if (request.getRequestURI().startsWith("/base/sample")) {
			log.debug("startWith intercept");
			return false;
		}
		return HandlerInterceptor.super.preHandle(request, response, handler);
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		log.debug("AccessInterceptor postHandle()");
		HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		log.debug("AccessInterceptor afterCompletion()");
		HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
	}
}

 

 

TokenInterceptor.java

package com.example.base.common.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class TokenInterceptor implements HandlerInterceptor {

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		log.debug("TokenInterceptor preHandle() :: ");
		log.debug("request.getRequestURI() : " + request.getRequestURI());
		if (request.getRequestURI().startsWith("/base/sample")) {
			log.debug("startWith intercept");
			response.setStatus(401);
			return false;
		}
		return HandlerInterceptor.super.preHandle(request, response, handler);
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		log.debug("TokenInterceptor postHandle()");
		HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		log.debug("TokenInterceptor afterCompletion()");
		HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
	}
}



 

preHandle : 핸들러가 실행되기 전에 실행됩니다. 또한 return이 true인 경우 다음으로 진행이 되는데 사용자의 로그인정보들이 비정상이라 판별되면 return false 해서 중단시킬 수도 있습니다.

 

postHandle : 핸들러가 실행이 되었고, 뷰 렌더링 이전에 실행됩니다. ModelAndViewr가 di되고있어서, 후 처리가 가능합니다.

 

afterCompletion : View가 전부 그려진 후 호출됩니다.

 

Request.UIR가 /base/sample로 시작하는경우 statusCode 401 응답한다.

startsWith 부분 주석하고서 디버깅하였는데 Mybatis 요청까지 끝내고나서 postHandle()가 실행되는것을 볼 수 있다.

시점을 잘 맞춰서 사용하면 될것같다.

 

예를들면 mybatis로 어떤 정보를 획득하였는데 공통적으로 repsonse할때 어떠한 처리를 해줘야하는경우 postHandle() 에서 그정보에 대한 처리를 해주는것으로 하면 될것같다.

 

 

interceptor를 추가하기 위한 WebMvcConfigurer를 상속받은 InterceptorConfig

package com.example.base.config;

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

import com.example.base.common.interceptor.AccessInterceptor;
import com.example.base.common.interceptor.TokenInterceptor;

@Configuration
@ComponentScan(basePackages = {"com.example.base"})
@EnableWebMvc
public class InterceptorConfig implements WebMvcConfigurer{
 
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new AccessInterceptor()).order(0).excludePathPatterns("/base/sample/currentDate");
        registry.addInterceptor(new TokenInterceptor()).order(1);
    }
}

 (공통으로 쓰는 클래스이름을 바꾸고 Web Configuration으로 써도된다.)

 

InterceptorRegistry의 addInterceptor로 interceptor를 추가할 수 있다.

 

order(int) : 인터센터 우선순서를 정할 수 있음.

 

excludePathPatterns("/base/sample/currentDate"); :

“Base/sample/currentDate” 경로는 예외로 진입못하게함.

 

반응형