오답노트
[Spring] Filter 본문
Filter
웹 어플리케이션에서 관리되는 영역으로써 Spring Boot Framework에서 Client로 부터 오는 요청/응답에 대해서 최초/최종 단계의 위치에 존재하며, 이를 통해서 요청/응답의 정보를 변경하거나, Spring에 의해서 데이터가 변환되기 전의 순수한 Client의 요청/응답 값을 확인 할 수 있다.
유일하게 ServletRequest, ServletResponse의 객체를 변환 할 수 있다.
주로 스프링에서는 요청과.응답의 logging 으로 활용하거나, 인증과 관련된 logic들을 해당 filter에서 처리한다.
이를 선/후 처리 함으로써, Service business logic과 분리 시킨다.
@SpringBootApplication
@ServletComponentScan
public class FilterApplication {
public static void main(String[] args) {
SpringApplication.run(FilterApplication.class, args);
}
}
메인 클래스에 ServletComponentScan Annotation을 등록한다.
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;
import java.io.IOException;
@Slf4j
@WebFilter(urlPatterns = "/api/user/*")
public class GlobalFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//전처리
ContentCachingRequestWrapper httpServletRequest = new ContentCachingRequestWrapper((HttpServletRequest)request);
ContentCachingResponseWrapper httpServletResponse = new ContentCachingResponseWrapper((HttpServletResponse)response);
chain.doFilter(httpServletRequest, httpServletResponse); // 내용이 들어감
//후처리
//req
String reqContent = new String(httpServletRequest.getContentAsByteArray());
String url = httpServletRequest.getRequestURI();
log.info("response status : {}, responseBody : {}",url, reqContent);
String resContent = new String(httpServletResponse.getContentAsByteArray());
int httpStatus = httpServletResponse.getStatus();
httpServletResponse.copyBodyToResponse();
log.info("response status : {}, responseBody : {}",httpStatus, resContent);
}
}
WebFilter Annotation으로 어떤 url에서 필터를 적용할지 지정한다.
Filter 인터페이스를 상속한 클래스를 만들고 doFilter를 Override한다.
요청과 응답에서 읽은 데이터는 모두 Stream이기 때문에 Filter에서 한 번 읽으면 다른 곳에서는 사용할 수 없다.
그래서 ContentCachingRequestWrapper와 ContentCachingResponseWrapper를 활용하면 Filter에서 읽더라도 다른 곳에서 읽을 수 있다.
chain.doFilter 메소드를 호출하면 요청과 응답에 있는 데이터를 가져온다.
'Java > Spring' 카테고리의 다른 글
[Spring] 비동기 처리 (Async) (0) | 2023.07.14 |
---|---|
[Spring] Interceptor (0) | 2023.07.14 |
[Spring] Exception과 Validation (0) | 2023.07.14 |
[Spring] Exception (0) | 2023.07.14 |
[Spring] Validation (0) | 2023.07.13 |