본문 바로가기

TIL

2026.1.27 - Spring Interceptor

Spring Interceptor

- Main Controller(Dispatcher Servlet)에서 HandlerMapper를 호출하기 전 혹은 Controller를 호출한 이후에 응답이나 최종적인응답을 참조하거나 변경할 수 있는 객체

- 개발자가 특정 작업을 수행하기 전 또는 수행한 이후에 작업을 가로채서 기능을 추가하거나 변경할 때 주로 사용 

- 필터는 요청하기 전(Servlet레벨에서 동작) 동작하며, 모든 HTTP에 대한 요청을 처리

- interceptor는 Spring HandlerMapping 단계부터 동작을 수행하여 Spring MVC에서 Controller에서만 적용됨.

- org.springframework.web.servlet.HandlerInterceptor Interface로 제공되며, default method이므로 업무를 할 수 있음.

preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
- DispatcherServlet -> HandlerMapper 과정에서 가로 챔
- Main Controller가 HandlerMapper를 실행하기 전에 처리할 작업이 있거나 요청정보를전처리(변경, 추가)해야하는 경우 사용.
- 여러 개의 interceptor가 등록되어 있을 경우 순차적으로 호출됨

return true : preHandle을 호출한 후 다음 작업(Controller 호출, Controller 이후 작업, Interceptor의 남은 작업)으로 진행함.
return false : preHandle을 호출한 후 다음 작업으로 진행하지 않음(예. 로그인을 하지 않은 상태라면 그 뒤에 작업을 수행하지 않음)
postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView)
- DispatcherServlet -> HTML 과정에서 가로챔
- Controller 이후 호출
- Controller에서 반환하는 ModelAndView를 받아서 반환되는 M.A.V 객체의 값을 처리할 수 있음
- 비동기 요청일 때는 호출되지 않음(비동기의 경우 ViewResolver를 호출하지 않기 때문)
- preHandle()에서 return false인 경우 호출되지 않음
- 여러 개의 interceptor가 등록되어 있을 경우 역순으로 호출됨 
afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable 
Exception ex)
- HTML -> Web browser 과정에서 가로챔 
- view를 생성한 후 응답되기 전에 호출됨
- 요청 시 사용된 자원들을 해제할 때 사용하면 적합함. 
- 비동기 요청일 때는 호출되지 않음
- preHandle()에서 return false인 경우 호출되지 않음
- 여러 개의 interceptor가 등록되어 있을 경우 역순으로 호출됨 

 

1. HandlerInterceptor를 구현하는 클래스 작성

@Component
public class MyInterceptor implements HandlerInterceptor {

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		System.out.println("preHandle : 요청이 컨트롤러에 도달하기 전에 실행됨");
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
		System.out.println("postHandle : 컨트롤러 실행 후 View가 랜더링되기 전에 실행됨");
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
		System.out.println("afterCompletion : 요청 완료 후 실행됨");
	}
	
}

 

2. Config 클래스(@Configuration)를 만들고 생성한 Interceptor를 의존성 주입해줌

/**
 * WebMvcConfigurer : 정적 리소스 매핑, 인터셉터 등록, CORS 설정
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {
	
	@Autowired
	private MyInterceptor myInterceptor;

}

 

3. Interceptor를 등록하는 method를 Override해주고 InterceptorRegistry에 생성한 Interceptor를 등록

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(myInterceptor);
}

 

4. Interceptor가 동작할 경로와 동작하지 않을 경로를 설정해줌

//**은 하위 모든 경로를 포함시킴
registry.addInterceptor(myInterceptor).addPathPatterns("/동작할 경로","/동작할 경로/**");
registry.addInterceptor(myInterceptor).excludePathPatterns("/동작하지 않을 경로","/동작하지 않을 경로/**");
registry.addInterceptor(myInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/helloMsg");

모든 경로에 동작할 경우
특정 경로를 제외시킬 경우


설정파일(properties)에 경로 설정

- List<String>에 의존성 주입을 하면 ,를 기준으로 잘라서 추가됨.

- /** : 최상위를 exclude에 설정해두면 addPath가 작동되지 않음(exclude 우선순위가 높음)

@Value("${user.addPath}")
private List<String> addPath;
@Value("${user.excludePath}")
private List<String> excludePath;

Interceptor 여러개 등록하기

registry.addInterceptor(myInterceptor)//user
.addPathPatterns("/**")
.excludePathPatterns("/helloMsg","/day0127/**");

registry.addInterceptor(myInterceptor2)//admin
.addPathPatterns(addPath)
.excludePathPatterns(excludePath);

preHandle은 순차적으로, postHandle과 afterCompletion은 역순으로 실행됨.


세션 값 확인

- 통제하는 변수를 하나로 만들어서 사용해야 함

- 조건에 따라 원하는 결과로 이동시킬 수 있음.

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
        throws Exception {
    //1. 세션 얻기
    HttpSession session = request.getSession();
    Object obj = session.getAttribute("userId");

    boolean flag = obj!=null; //값이 있으면 true
    if(!flag) { //값이 없을 때 이동시킴
        response.sendRedirect("http://localhost:8080/login/loginFrm");
    }
    return flag;
}

 

'TIL' 카테고리의 다른 글

2026.2.10 ~ 13 - DevOps(Docker)  (0) 2026.02.10
2025.9.29 - JDBC  (0) 2025.09.29