스프링에서 공통적으로 처리할 로직을 구현하고 싶을 때가 있어요.
대표적으로 Java Filter, Spring Interceptor, Spring AOP를 활용할 수 있는데요.
이 글에선 Interceptor를 활용하여 특정 URI들의 요청을 가로채서 역할을 수행할 수 있도록 구현해볼거에요.
Interceptor는 Spring Container 영역이며 Servlet 단위에서 실행되요.
인증/권한 처리, 로직 시간 계산, 로깅 등을 공통적으로 처리하고 싶을 때 사용해요.
AuthInterceptor
이름만 Auth로 써봤어요. 실제로는 로그만 찍을겁니다.
AuthInterceptor 클래스에 HandlerInterceptor 인터페이스를 구현할거에요.
스프링에서 다해줘요. 우리는 비즈니스 로직만 구현하면 되요.
특정 Request를 호출할 때마다 AuthInterceptor에서 구현한 메서드가 동작해요.
- preHandle : @Controller 호출 이전에 동작
- postHandle : @Controller 호출 이후에 동작
- afterCompletion : 화면 처리까지 모두 끝나면 동작
정확하게는 @Controller가 아니라 HandlerAdapter가 핸들러를 호출하는 시점이지만, 이해하기 쉽도록 지금은 @Controller 정도로 알고 계셔도 될 것 같아요.
궁금하신 분은 Spring Framework HandlerAdapter에 대해서 찾아보시면 어렵지 않게 이해할 수 있을 거에요.
@Slf4j
@Component
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
log.info("preHandle!!");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
log.info("postHandle!!");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
log.info("afterCompletion!!");
}
}
WebMvcConfig
구현한 인터셉터를 사용할 수 있도록 설정할거에요.
/user/로 시작하는 패턴은 가로채지 못하도록 제외하였어요.
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private AuthInterceptor authInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authInterceptor)
.addPathPatterns("/event/**")
.excludePathPatterns("/user/**");
}
}
EventController
@Slf4j
@RestController
@RequestMapping("event")
public class EventController {
@Autowired
private EventsRepo eventsRepo;
@GetMapping("")
public Page<EventsDoc> getList(Pageable pageable) {
log.info("Event!!");
return eventsRepo.findAll(pageable);
}
}
테스트해볼게요.
http://localhost:8080/event
http://localhost:8080/user
호출하면 인터셉트의 로직을 수행하지 않음을 확인할 수 있어요.
아래와 같은 부분들 잘 판단해서 적용하시면 좋을 것 같아요.
- REST 아키텍처에서는 Interceptor 도입하기 전에 고려해야할 사항이 있어요. Interceptor는 URI 패턴을 체크하여 요청을 가로채는데 REST는 URI 패턴이 같으면서 Method가 다른 요청들이 많기 때문이죠.
- URI 패턴에 공통적인 부분이 별로 없을 때 Interceptor를 사용하면 불리해요. 이런 경우에는 일반적으로 설계하듯이 로직을 객체화한 후 수행할 컨트롤러의 메서드에 일일이 추가해주는 것이 수월할 수도 있어요.
'Backend > Spring' 카테고리의 다른 글
JPA 작성자, 수정자 자동 세팅 Auditor (0) | 2019.11.11 |
---|---|
JPA @ManyToOne Join (Only JpaRepository) (0) | 2019.11.11 |
Spring Boot Session MySQL 연동, 저장 (1) | 2019.10.16 |
Spring Boot Session MongoDB 연동, 저장 (0) | 2019.10.16 |
Spring Boot Session Redis 연동, 저장 (2) | 2019.10.16 |