spring boot/spring boot

spring boot 에서 interceptor

ballde 2021. 12. 4. 21:26

이전에 filter에 대해 보았습니다.

https://balldev.tistory.com/41

[spring의 dispatcher-servlet와 filter

dispatcher servlet 이 해당 애플리케이션으로 들어오는 모든 요청을 핸들링 해주고 공통 작업을 처리하면서 편리하게 이용이 가능하다!! ** 예전에는 모든 서블릿에 대해 URL 매핑을 web.xml에 해줬어야

balldev.tistory.com](https://balldev.tistory.com/41)

  • 인터셉터는 컨트롤러 가기 전, 후로 나뉩니다.
  • 인증관리 등 여러경우에 은근 쓰이는것 같습니다.

filter와의 차이

  • 사진을 보시는 것과 같이 filter와의 차이는 dispatcher servlet의 앞에 있냐 뒤에 있냐입니다.
  • 그리고 인터셉터는 스프링 컨텍스트 안에 있고 filter는 그것보다 더 앞에 있습니다.
  • 그래서 filter는 spring context안에 없습니다. web application에 등록돼서 스프링 Ioc가 관리하는 빈에 접근하지 못합니다.
public class SampleInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object object, @Nullable Exception arg3) throws Exception {
    }
}
  • preHandler : 컨트롤러에 도착하기전에 동작하는 메소드
  • postHandler : 컨트롤러에 도착하여 view가 랜더링되기 전에 동작
  • afterCompletion: view가 정상적으로 랜더링된 후에 마지막에 실행

그리고 이 인터셉터를 등록을 해주어야 합니다.

@Configuration
@RequiredArgsConstructor
public class SampleConfigure implements WebMvcConfigurer{
    private final SampleInterceptor sampleInterceptor;
    //인터셉터 주소 세팅
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(sampleInterceptor)
    }
}

하나의 예시로 아이피 체크를 interceptor로 해보겠습니다.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface IPCheck {
}

IPCheck라는 어노테이션을 만들어줍니다.

@Component
public class IPCheckInterceptor implements HandlerInterceptor {

    List<String> ipList = Arrays.asList("127.0.0.1", "localhost");

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // HandlerMethod 타입인지 체크
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;

        IPCheck ip = handlerMethod.getMethodAnnotation(IPCheck.class);

        // method @IPCheck 가 없는 경우, 즉 인증이 필요 없는 요청
        if (ip == null) {
            return true;
        }
        // 접속한 사용자의 ip 체크
        System.out.println("request = " + request.getRemoteAddr());
        if (!ipList.contains(request.getRemoteAddr())) {
            throw new IPCheckException();
        }
        return true;
    }

}

특정 어노테이션이 있으면 그 컨트롤러는 localhost에서만 작동하게 합니다.

@Configuration
@RequiredArgsConstructor
public class SampleConfigure implements WebMvcConfigurer{
    private final IPCheckInterceptor sampleInterceptor;
    //인터셉터 주소 세팅
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(IPCheckInterceptor)
    }
}

이 인터셉터를 등록해줍니다.

ps. 이러한 경우에는 filter를 써도 무방할 것 같네요 ㅎㅎ