LoginSignup
0
4

More than 5 years have passed since last update.

RestTemplateのリクエスト・レスポンスをログ出力する

Posted at

概要

Springフレームワークで提供されているRestTemplateによるWebAPIの実行をログ出力したい。

環境

  • Java 8
  • SpringBoot 2.1.3.RELEASE
  • Spring 5.1.5.RELEASE
  • Lombok 1.18.6

RestTemplateClientHttpRequestInterceptorを差し込む

  • RestTemplateのリクエスト・レスポンスに介入するインターセプタを利用する

ログ出力を行うインターセプタ

  • 注意点
    • レスポンスボディは一回しか読めない。ログ出力のためにインターセプタでレスポンスボディを読み込むと、RestTemplateの呼び出し元には空のボディが返ってしまう。
      • 後述のBean定義におけるBufferingClientHttpRequestFactoryの設定で回避する。
RestTemplateのインターセプタ
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.util.StreamUtils;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.UUID;

@Slf4j
public class RestTemplateLoggingInterceptor implements ClientHttpRequestInterceptor {

    @Override
    public ClientHttpResponse intercept(HttpRequest request,
                                        byte[] body,
                                        ClientHttpRequestExecution execution) throws IOException {
        val requestUuid = UUID.randomUUID();
        logRequest(requestUuid, request, body);
        val response = execution.execute(request, body);
        logResponse(requestUuid, response);
        return response;
    }

    private void logRequest(UUID requestUuid, HttpRequest request, byte[] body) {
        if (log.isInfoEnabled()) {
            log.info("[API:Request({})] Request=[{}:{}], Headers=[{}], Body=[{}]",
                requestUuid,
                request.getMethod(),
                request.getURI(),
                request.getHeaders(),
                new String(body)
            );
        }
    }

    private void logResponse(UUID requestUuid, ClientHttpResponse response) throws IOException {
        if (log.isInfoEnabled()) {
            log.info("[API:Response({})] Status=[{}:{}], Headers=[{}], Body=[{}]",
                requestUuid,
                response.getStatusCode().value(),
                response.getStatusText(),
                response.getHeaders(),
                StreamUtils.copyToString(response.getBody(), StandardCharsets.UTF_8)
            );
        }
    }

}

RestTemplateのBean定義

  • ログ出力を行うインターセプタを設定したRestTemplateをBean定義する。
    • BufferingClientHttpRequestFactoryを利用し、ログ出力インターセプタの問題を回避する。
@Configuration
public class ExternalApiConfig {

    @Bean
    RestTemplate restTemplate() {
        return new RestTemplateBuilder()
            .requestFactory(() -> new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory()))
            .additionalInterceptors(new RestTemplateLoggingInterceptor())
            .build();
    }

}

参考

RestTemplateでリクエストやレスポンスの中身をログに出す

0
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
4