Servlet Filter 적용

박상우·2023년 7월 18일

Srping

목록 보기
3/5

Filter

Filter 란?
Dispatcher Servlet 에 요청이 전달되기 전,후 해당 URL 패턴에 맞는 모든 요청에 대하여 부가적인 검증을 할 수 있도록 하는 것

Filter 메서드 종류

  • init 메서드
    • 필터 객체를 초기화하고 서비스에 추가하기 위한 메서드
    • 웹 컨테이너에서 1회 호출하여 객체 초기화
  • doFilter 메서드
    • URl 패턴에 맞는 HTTP 요청이 Dispatcher Servlet으로 전달되기 전에 웹 컨테이너에 의해 실행되는 메서드
    • doFilter의 파라미터로 FilterChain이 있으며 해당 FilterChain의 doFilter 메서드를 통해 다음 대상으로 요청을 전달
    • doFilter() 전/후에 우리가 필요한 처리 과정을 넣어 원하는 처리를 하도록 할수 있음
  • destory 메서드
    • Filter 객체를 서비스에서 제거하고 자원을 반환
    • 웹 컨테이너에 의해 1회 호출되며 이후 doFilter 처리하지 않음

아래 코드는 Filter 적용 예시 코드

@Slf4j
@Component
public class LoggerFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        ContentCachingRequestWrapper req = new ContentCachingRequestWrapper((HttpServletRequest) request);
        ContentCachingResponseWrapper res = new ContentCachingResponseWrapper((HttpServletResponse) response);

        chain.doFilter(req, res);

        String uri = req.getRequestURI();
        String method = req.getMethod();
        Enumeration<String> headerNames = req.getHeaderNames();
        StringBuilder headerValues = new StringBuilder();
        String requestBody = new String(req.getContentAsByteArray());

        headerNames.asIterator().forEachRemaining(headerName -> {
            String value = req.getHeader(headerName);
            headerValues.append(headerName).append(":").append(value).append(", ");
        });

        log.info("============ http request ============");
        log.info("uri: {}, method: {}", uri, method);
        log.info("reqHeader: [{}]", headerValues);
        log.info("requestBody: {},", requestBody);


        StringBuilder resHeaderValues = new StringBuilder();

        res.getHeaderNames().forEach(resHeaderName -> {
            String value = res.getHeader(resHeaderName);
            resHeaderValues.append(resHeaderName).append(":").append(value).append(", ");
        });

        String resBody = new String(res.getContentAsByteArray());

        log.info("resHeader: [{}]", resHeaderValues);
        log.info("resBody: {}", resBody);
        log.info("======================================");

        res.copyBodyToResponse();
    }
}
  • ContentCachingRequestWrapper, ResponseWrapper 객체를 이용하여 Request, Response의 데이터를 사용할 수 있음
  • FilterChain.doFilter() 메서드를 호출하여 요청 처리 이후, 응답 전에 원하는 검증 처리
  • 반드시 Wrapper를 통해 가져온 데이터는 Response Wrapper의 copyBodyToResponse() 메서드를 호출하여 클라이언트에 응답값을 전달할 수 있도록 해야 함
profile
보안, 개발을 같이 하고 있습니다

4개의 댓글

comment-user-thumbnail
2023년 7월 18일

이런 정보를 찾고 있었습니다, 감사합니다.

1개의 답글
comment-user-thumbnail
2023년 7월 18일

잘 읽었습니다. 좋은 정보 감사드립니다.

1개의 답글