본문 바로가기
스프링/스프링부트

[Spring Boot] 스프링 MVC 인터셉터란? 스프링 부트에서 사용하기

by 책 읽는 개발자_테드 2021. 11. 4.
반응형

학습 목표

· 인터셉터란?

· 의존성 추가

· 스프링 부트에서 인터셉터 사용하기


인터셉터란?

·  Spring Interceptor는 클라이언트 요청을 가로채서 처리하는 데 사용된다.

·  스프링에서 요청이 컨트롤러로 전송되면 컨트롤러에서 처기되기 전, 컨트롤러에서 응답을 받은 후에 클라이언트에 응답을 보내기 전, 응답 완료 후(뷰가 렌더링 된 후)에 Interceptor를 통과한다.

·  로깅 및 권한 인증 확인 등 반복적인 처리 코드를 피하는 데 도움을 줄 수 있다.

https://o7planning.org/11229/spring-mvc-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)

 

각 요청은 여러 개의 인터셉터를 통과할 수 있다.

https://o7planning.org/11229/spring-mvc-interceptor

의존성 추가

 

인터셉터를 이용하려면, 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

https://www.baeldung.com/spring-mvc-handlerinterceptor

https://o7planning.org/11229/spring-mvc-interceptor

반응형

댓글