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
@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 HandlerInterceptor.super.preHandle(request, response, handler);
}
@Override
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);
}
}
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) 모든 주소를 검증(특정 어노테이션을 가지고 있을때만)
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
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를 통해 높은 값이 먼저 실행 되도록 할 수있다