학습 목표
· 인터셉터란?
· 의존성 추가
· 스프링 부트에서 인터셉터 사용하기
인터셉터란?
· Spring Interceptor는 클라이언트 요청을 가로채서 처리하는 데 사용된다.
· 스프링에서 요청이 컨트롤러로 전송되면 컨트롤러에서 처기되기 전, 컨트롤러에서 응답을 받은 후에 클라이언트에 응답을 보내기 전, 응답 완료 후(뷰가 렌더링 된 후)에 Interceptor를 통과한다.
· 로깅 및 권한 인증 확인 등 반복적인 처리 코드를 피하는 데 도움을 줄 수 있다.
인터셉터는 org.springframework.web.servlet.HandlerInterceptor 인터페이스를 구현하거나,
org.springframework.web.servlet.handler.HandlerInterceptorAdapter 클래스를 상속하여 사용할 수 있다.
이때, 다음 세 가지 추상 메서드를 구현해야한다.
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
- public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView)
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
각 요청은 여러 개의 인터셉터를 통과할 수 있다.
의존성 추가
인터셉터를 이용하려면, spring-web 의존성을 추가해야한다.
Maven
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Gradle
compile('org.springframework.boot:spring-boot-starter-web')
스프링 부트에서 인터셉터 사용하기
인터셉터를 사용하려면, 다음과 같은 작업이 필요하다.
1. 인터셉터를 지원하는 @Component 클래스를 생성한다.
2. HandlerInterceptor 인터페이스를 구현해야 한다. (또는 HandlerInterceptorAdapter 상속)
3. 인터셉터를 사용하기 위한 세 가지 추상 메서드를 구현한다.
- preHandle(): 컨트롤러에 요청을 보내기 전에 작업을 수행하는 데 사용된다.
이 메서드가 클라이언트에게 응답을 반환하려면, true를 리턴해야 한다.
- postHandle(): 클라이언트에 응답을 보내기 전에 작업을 수행하는 데 사용된다.
- afterCompletion(): 요청 및 응답을 완료한 후 작업을 수행하는 데 사용된다.
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Component
public class ProductServiceInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle
(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("Pre Handle method is Calling");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("Post Handle method is Calling");
}
@Override
public void afterCompletion
(HttpServletRequest request, HttpServletResponse response, Object
handler, Exception exception) throws Exception {
System.out.println("Request and Response is completed");
}
}
4. WebMvcConfigurerAdapter를 사용해서 InterceptorRegistry에 위에서 만든 인터셉터를 등록한다.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Component
public class ProductServiceInterceptorAppConfig extends WebMvcConfigurerAdapter {
@Autowired
ProductServiceInterceptor productServiceInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(productServiceInterceptor);
}
}
수정사항: 스프링 5.0 부터는 WebMvcConfigurerAdapter 추상클래스가 deprecated 대신 WebMvcConfigurer 인터페이스를 구현하여 사용한다.
@Component
public class ProductServiceInterceptorAppConfig implements WebMvcConfigurer {
@Autowired
ProductServiceInterceptor productServiceInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(productServiceInterceptor);
}
}
마지막으로 지금까지 작성한 인터셉터로 가로챌 요청을 받는 컨트롤러 클래스를 작성하고, 요청을 보내 결과를 확인한다.
@RestController
public class ProductServiceController {
private static Map<String, Product> productRepo = new HashMap<>();
static {
Product honey = new Product();
honey.setId("1");
honey.setName("Honey");
productRepo.put(honey.getId(), honey);
Product almond = new Product();
almond.setId("2");
almond.setName("Almond");
productRepo.put(almond.getId(), almond);
}
@RequestMapping(value = "/products")
public ResponseEntity<Object> getProduct() {
return new ResponseEntity<>(productRepo.values(), HttpStatus.OK);
}
}
class Product {
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
결과
출처
https://www.tutorialspoint.com/spring_boot/spring_boot_interceptor.htm
'스프링 > 스프링부트' 카테고리의 다른 글
[Spring Boot] AOP란? 스프링부트에서 AOP 사용하기 (0) | 2021.11.10 |
---|---|
스프링 부트 AutoConfigure가 작동하는 원리 (0) | 2021.10.26 |
[Spring Boot]스프링부트와 Gradle을 통해 Swagger 2 시작하기 (0) | 2021.05.22 |
[JUnit] 스프링부트 + junit5 환경에서 MockMvc로 컨트롤러 테스트하기 (0) | 2021.04.29 |
[Spring Boot] 오류 해결: (org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing) (2) | 2021.04.28 |
댓글