반응형
스프링 부트에서 사용되는 Interceptor의 동작원리를 알아보자
1. 스프링부트에서 인터셉터란?
스프링부트에서의 인터셉터
- 스프링부트에서 인터셉터는 웹 애플리케이션에서 요청과 응답을 처리하는 중간 단계에서 사용된다. 인터셉터는 특정 URI 패턴에 대한 요청을 가로채어, 컨트롤러가 처리하기 전후에 추가적인 작업을 할 수 있게 해 준다. 이를 통해, 로그인 체크, 권한 검증, 로깅 등과 같은 작업을 효율적으로 처리할 수 있다.
인터셉터의 동작 과정
- 클라이언트로부터 들어오는 요청(HttpRequest)을 가로챈다.
- 가로챈 요청에 대해 원하는 처리(예: 로그인 체크, 권한 체크 등)를 수행한다.
- 처리가 끝난 후, 요청을 원래의 목적지인 컨트롤러로 전달한다.
- 컨트롤러가 응답(HttpResponse)을 반환하면, 이 응답 역시 가로챌 수 있다.
- 가로챈 응답에 대해 원하는 처리(예: 응답 로깅 등)를 수행한 후, 응답을 클라이언트로 전달한다.
2. interceptor 사용예시 (xml 사용)
지금부터 스프링부트에서 Interceptor를 사용하는 예시를 확인해 보자
이 예시에서는 인터셉터를 사용하여 로그인 처리를 하는 방법을 보여준다.
먼저, 인터셉터를 설정하는 방법부터 살펴보자.
- 스프링 설정 파일에서 인터셉터를 설정할 수 있다. 아래의 설정은 모든 요청을 가로채서 com.victolee.interceptor 패키지에 있는 MyInterceptor 객체를 실행하겠다는 의미다.
<!-- Interceptors -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="com.victolee.interceptor.MyInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
다음으로, 인터셉터를 구현하는 방법을 살펴보자.
- 인터셉터를 구현하기 위해서는 HandlerInterceptor 인터페이스를 구현하거나 HandlerInterceptorAdapter 클래스를 상속받아야 한다.
public class MyInterceptor implements HandlerInterceptor {
// controller로 보내기 전에 처리하는 인터셉터
// 반환이 false라면 controller로 요청을 안함
// 매개변수 Object는 핸들러 정보를 의미한다. ( RequestMapping , DefaultServletHandler )
@Override
public boolean preHandle(
HttpServletRequest request, HttpServletResponse response,
Object obj) throws Exception {
System.out.println("MyInterCeptor - preHandle");
return false;
}
// controller의 handler가 끝나면 처리됨
@Override
public void postHandle(
HttpServletRequest request, HttpServletResponse response,
Object obj, ModelAndView mav)
throws Exception {
}
// view까지 처리가 끝난 후에 처리됨
@Override
public void afterCompletion(
HttpServletRequest request, HttpServletResponse response,
Object obj, Exception e)
throws Exception {
}
}
- 위의 코드에서 preHandle 메서드는 컨트롤러가 호출되기 전에 실행되며, postHandle 메서드는 컨트롤러가 실행된 후에 호출되고, afterCompletion 메서드는 뷰에서 최종 결과가 생성하는 일을 포함한 모든 일이 완료 되었을 때 실행된다.
마지막으로, 로그인 처리를 위한 인터셉터를 구현하는 예제를 살펴보자
- 아래의 코드에서는 AuthLoginInterceptor가 HandlerInterceptorAdapter를 상속받아 preHandle 메서드를 오버라이딩 하여 로그인 처리를 수행한다.
- 클라이언트가 로그인 버튼을 눌렀을 때 email과 pwd를 전달한다고 가정하면, getParameter 메서드로 데이터를 가져올 수 있고 UserVO를 Service 계층에 전달하여 해당 유저가 존재하는지 확인한다.
public class AuthLoginInterceptor extends HandlerInterceptorAdapter {
@Autowired
private UserService userService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
String email = request.getParameter("email");
String pwd = request.getParameter("pwd");
UserVO vo = new UserVO();
vo.setEmail(email);
vo.setPwd(pwd);
userService.getUser(vo);
return false;
}
}
이렇게 인터셉터를 활용하면, 로그인 처리와 같은 반복적인 작업을 컨트롤러에서 분리하여 코드의 중복을 줄이고 관리를 용이하게 할 수 있다.
3. interceptor 사용예시 (@Configuration 어노테이션 사용)
이 예시에서는 @Configuration 어노테이션을 적용시킨 후 로그를 출력하는 간단한 인터셉터를 만들어보겠다.
먼저, HandlerInterceptor 인터페이스를 구현하는 LoggerInterceptor 클래스를 만들어보자
- 아래의 LoggerInterceptor 클래스는 HandlerInterceptor 인터페이스를 구현하고 있으며, preHandle 메서드와 postHandle 메서드를 오버라이드하고 있다.
- preHandle 메서드는 컨트롤러가 호출되기 전에 실행되며, postHandle 메서드는 컨트롤러가 실행된 후에 호출된다. 이 예시에서는 각 메서드에서 로그를 출력하도록 구현하였다.
package com.study.interceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Slf4j
public class LoggerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.debug("===============================================");
log.debug("==================== BEGIN ====================");
log.debug("Request URI ===> " + request.getRequestURI());
return HandlerInterceptor.super.preHandle(request, response, handler);
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.debug("==================== END ======================");
log.debug("===============================================");
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
}
다음으로, WebMvcConfigurer 인터페이스를 구현하는 WebMvcConfig 클래스를 만들어보자. 이 클래스에서 인터셉터를 등록한다.
- 아래의 WebMvcConfig 클래스는 WebMvcConfigurer 인터페이스를 구현하고 있으며, addInterceptors 메서드를 오버라이드하고 있다. addInterceptors 메서드에서는 LoggerInterceptor를 등록하고, 특정 패턴의 경로를 인터셉터의 적용에서 제외하고 있다.
package com.study.config;
import com.study.interceptor.LoggerInterceptor;
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 LoggerInterceptor())
.excludePathPatterns("/css/**", "/images/**", "/js/**");
}
}
📌 마무리
이렇게 설정하면, 인터셉터가 정상적으로 동작하게 된다. 이 예시에서는 모든 요청에 대해 요청 URI를 로그로 출력하게 된다. 참고로, 이 예시는 스프링 부트 2.x 버전을 기준으로 작성되었다. 스프링 부트 3에서도 동일하게 적용할 수 있다.
필터가 인터셉터와 다른점을 알아보자👇🏻👇🏻
반응형
'Spring 기초 > Spring 기초 지식' 카테고리의 다른 글
[스프링, 스프링 부트] Spring - ajax로 호출하는 controller 메서드 구현방법 (2) | 2023.08.22 |
---|---|
Spring: Maven과 Gradle의 차이 (0) | 2023.08.17 |
Spring MVC의 Model, ModelAndView, ModelMap 비교 (0) | 2023.08.13 |
Spring에서의 인스턴스 생성 비교: new 키워드 대 DI (0) | 2023.08.13 |
스프링에서의 데이터베이스 접근 방법: DAO, Mapper, 그리고 @Mapper 어노테이션 사용법 (0) | 2023.08.09 |