スプリングの各種機能(Filter、Interceptor)


Filter-Interceptorを使用します。


🔔😁🎅🤔

🤔🤔🤔Filterって何ですか?


Filterは、クライアントからのリクエスト/レスポンスに対するspring Bootの最初/最終段階の位置にあるWebアプリケーション管理領域であり、リクエスト/レスポンスの情報を変更したり、Springでデータを変換する前に純粋なクライアントのリクエスト/レスポンス値を表示したりすることができます.
サーブレットRequest、サーブレットResponseを変換できる唯一のオブジェクトです.
主にrequest/responseのログ・レコードに使用されるか、またはHeadFliterで認証に関連するログを処理します.
サービスビジネスロジックから前後処理で分離します.
異なる点は,AOPマッピングがオブジェクトであるためSpringに入るため純粋ではないことである.
Filter-->DispatcherService-->Handler Interceptor-->AOP動作
画面から見る.

百聞は一見にしかず


要求と応答の内容をログに保持するFilterを作成します。


User.class設定ApicControllerを作成します.
@Slf4j
@Component //Spring Bean으로 관리되어야함
public class GlobalFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        //전처리
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;

        String url = httpServletRequest.getRequestURI();

        BufferedReader br = httpServletRequest.getReader();
        br.lines().forEach(line -> {
            log.info("url : {}, line: {}",url , line);
        });

    }
}
slf 4 jを使用してログ印刷を行う場合は、このフィルタを使用します.

こんなに上手に撮れました

🔔 でも!


FilterでBufferedReaderを使用します.
BufferedReaderの特性は、一度コンテンツを読むと、後ろでコンテンツが読めないと消えてしまう!!

🤔 ふん??どうしよう。サーブレットリクエストでLOGは撮れないのでしょうか?いいえ、次のようにすればいいです。


ContentCachingRequestWrapperを使用します。


ContentCatchingResquestWrapperの中のByteArrayOutputStreamにはあらかじめ内容を入れておき、後から誰かが読んでいるときは後から読むことができます.
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);
        //이렇게 한다고 해도 Byte의 길이만 설정해 두고 컨탠츠들은 복사하지 않는다 그래서 doFilter 다음에 실행시킨다.

        chain.doFilter(httpServletRequest, httpServletResponse);
        //후처리

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

        String resContent = new String(httpServletResponse.getContentAsByteArray());
        int httpStatus = httpServletResponse.getStatus();
        //Response도 마찬가지로 한번 읽으면 사라진다. 그래서 다시 채워줘야한다.ㅉ
        httpServletResponse.copyBodyToResponse(); //다시한번 더 바디를 채워준다.

        log.info("response status : {}, responseBody : {}", httpStatus, resContent);

    }
}

うわぁ~!~~これでよく記録できます。


最後にFilter範囲を設定

@Slf4j
@WebFilter(urlPatterns = "/api/user/*")
@Component //Spring Bean으로 관리되어야함
public class GlobalFilter implements Filter {
これで終わりFilterにログを残す

これはいいですねとてもいいです~~!