Filter & Intercepter

이서영·2024년 5월 30일

SpringBoot

목록 보기
5/7

Filter & Intercepter

Filter

  • 필터는 web context라고 해서 보통 톰캣이라는 영역에서 관리하는 영역이다.
  • 클라이언트로 부터 올라온 리퀘스트에 가장 날 것의 데이터가 들어았다.
  • 주로 들어온 데이터를 변환시켜 보내주거나 들어온 데이터에 대해서 기록을 해주는 로그 시스템을 가장 많이 활용
public class UserApiController {
    @PostMapping("")
    public void register(HttpEntity http){
        log.info("{}",http.getBody());
    }
}
  • 이렇게 해서 가능 하다
  • 하지만 한번더 캐스팅을 해야하는 불편함이 있기때문에 filter역활을 하는 것을 새로 생성

filter생성

package com.filter.filter;

import jakarta.servlet.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Component // 해당 클래스를 spring bin으로 등록을 하겠다.
@Slf4j
public class LoggerFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// 진입전
        log.info("진입전");
        filterChain.doFilter(servletRequest,servletResponse);
// 진입 후
        log.info("진입후");
    }
}
  • 해탕 필터에서는 최전방에 있기때문에 들어올때와 나갈때가 가능하고 servletRequest와 servletResponse를 조작 가능

ii)filter

Intercepter

  • 정상적인 데이터가 들어왔는지 또는 주소를 보고 해당 주소로 보내는 컨트롤러에 어떠한 권한을 가지고 있는지 검증
  • handler mapping 후에 전달이 되는데 controller가 이미 정해져 있고 어디로 가야 될지 목적지가 다 정해진 다음에 나오기에 여러가지를 컨트롤 가능 -> 어떠한 컨트롤러로 보낼것인가 어떠한 주소에 맵핑할 것인지 지정 가능
package com.filter.intercepter;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

@Component
public class OpenApiIntercepter implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //return true면 controller로 전달
        // default
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }

    @Override
    //model&뷰 화면에 연결이 되면 호출

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    //완료시 호출
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}
  • 추가로 config설정
package com.filter.config;

import com.filter.intercepter.OpenApiIntercepter;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
@RequiredArgsConstructor
public class WebConfig implements WebMvcConfigurer {
    private final OpenApiIntercepter openApiIntercepter;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(openApiIntercepter).addPathPatterns("/**");

    }
}
  • 모든 경로를 맵핑

II) 주소 검증

ii) 모든 주소를 검증(특정 어노테이션을 가지고 있을때만)

// hanlder 형변환 & 해당 컨트롤러 또는 메소드에 어노테이션 있는지 체크
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //return true면 controller로 전달
        // default
       // return HandlerInterceptor.super.preHandle(request, response, handler);
        var handlerMathod = (HandlerMethod)handler;
        var methodLevel = handlerMathod.getMethodAnnotation(OpenApi.class);
        if(methodLevel != null)
        {
            return true;
        }
        var classLevel = handlerMathod.getBeanType().getAnnotations(OpenApi.class);
        if(classLevel != null)
        {
            return true;
        }
        return false;x
    }


// 어노테이션 커스텀
package com.filter.intercepter;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.foreign.ValueLayout;

@Target(value = {ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface OpenApi {


}
  • 추가로 config에서 registry에 인터셉터를 등록하는데 인터셉터가 여러개가 있다면 add한 순서대로 아니면 .order를 통해 높은 값이 먼저 실행 되도록 할 수있다
profile
전공자 학생

0개의 댓글