[Spring] filter란?

fooooif·2021년 5월 14일
0
post-thumbnail

✍ 포스팅 할 내용

스프링 Project를 공부하다 Filter라는 개념이 나왔다. Filter를 사용하기 위해 공부했지만 정확한 이해가 필요한 것 같아 내용을 정리해본다.

☝ 필터란 무엇인가?

HTTP 요청과 응답을 변경할 수 있는 재사용 가능한 코드이다. 유일하게 ServletRequest, ServletResponse의 객체를 변환 할 수 있다.
Web Application에서 관리되는 영억으로써 Spring Boot Famework에서 Client로 부터 오는 요청/응답에 대해서 최초/최종 단계의 위치에 존재하며, 이를 통하여 요청/응답의 정보를 변경하거나, Spring에 의해서 데이터가 변환되기 전에 순수한 Clint의 요청/응답 값을 확인 할 수 있다.

✌ 필터의 기본구조


<출처: https://twofootdog.github.io/Spring-%ED%95%84%ED%84%B0(Filter)%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80/>

Servlet Contatiner가 클라이언트에게 받을 수 있는 request는 필터를 거쳐서 받게되고 반대로 클라이언트가 받게되는 response는 필터를 거쳐서 받게된다. 이때 필터가 여러가지 있을 수 있는데 이것을 필터 체인(Filter Chain)이라고 부른다. 필터는 클라이언트의 요청을 필터체인의 다음단계에 보내는 것이 아니라, 다른 자원의 결과를 클라이언트에 전송할 수도 있다. 필터의 이러한 기능은 사용자 인증이나 권한 체크와 같은 곳에서 사용 가능하다.

👌필터 사용하기


public void init(FilterConfig filterConfig) - 필터를 웹 콘테이너에 생성 후 초기화할 때 호출됩니다.
public void doFilter(ServletRequest request, SevletResponse response, FilterChain chain) - 필터체인으로 연결하여 줍니다. 체인의 경우 순서를 지정할 수 있습니다. 체인의 가장 마지막에는 클라이언트가 요청한 최종 자원이 위치합니다.
public void destroy() - 필터가 웹 콘테이너에서 삭제될 때 호출됩니다.

🖖코드 작성

공부를 하며 만든 custom filter입니다.
필터를 하나만 사용하기 때문에 init()과 destroy() 사용하지 않았습니다.

@Slf4j
@WebFilter(urlPatterns = "/api/user/*") 
// 특정 url(여러가지 가능)에만 필터 넣어주려면 + 돌아가는데에 @ServletComponentScan 적용
//아니면 @Component => 전체에
public class GlobalFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        //전처리
        //밑에 두줄은 Content 길이만 생성해주고 밑에 doFilter에서 byteArray에 내용이 들어간다.
        ContentCachingRequestWrapper httpServletRequest = new ContentCachingRequestWrapper((HttpServletRequest) request);
        ContentCachingResponseWrapper httpServletResponse = new ContentCachingResponseWrapper((HttpServletResponse) response);

        //doFilter이후에 찍어야된다.


        chain.doFilter(httpServletRequest,httpServletResponse);
        String url = httpServletRequest.getRequestURI();
        //후처리
        //req

        String reqContent = new String(httpServletRequest.getContentAsByteArray());
        log.info("request status : {}, requestBody : {}",url,reqContent);


        //여기서 내용을 다빼버리기 떄문에 밑에 copyBodyToResponse() 사용!
        String resContent = new String(httpServletResponse.getContentAsByteArray());
        int httpStatus = httpServletResponse.getStatus();


        httpServletResponse.copyBodyToResponse();

        log.info("response status : {}, responseBody : {}",httpStatus, resContent);
    }
}
profile
열심히 하자

1개의 댓글

comment-user-thumbnail
2021년 8월 5일

안녕하세요 글읽고 궁금한것이 있어 댓글남깁니다..
제가 지금 ajax로 object형식으로 데이터를 post 보내는데요 위에 올려주신 reqContent에 String형식으로 나오는데 저 중에 한가지 데이터에만 접근하는 방법이 있을까요?

답글 달기