今回はSpringのRestTemplateでログを出力する方法についてです。
RestTemplateで外部APIを実行するとレスポンスが返ってくるのですがInputStreamなので一度しか読み込めません。 (再オープン不可)
ログを出すために読み込んだら結果が出ぬ!ということを避けるためにはWrapperクラスをかます必要があります。
環境
- Java8
- Spring boot 1.5.6
実装方法
まずWrapperクラスを用意。
public class ClientHttpResponseWrapper implements ClientHttpResponse {
private final ClientHttpResponse response;
private byte[] body;
ClientHttpResponseWrapper(ClientHttpResponse response) {
this.response = response;
}
@Override
public HttpStatus getStatusCode() throws IOException {
return this.response.getStatusCode();
}
@Override
public int getRawStatusCode() throws IOException {
return this.response.getRawStatusCode();
}
@Override
public String getStatusText() throws IOException {
return this.response.getStatusText();
}
@Override
public HttpHeaders getHeaders() {
return this.response.getHeaders();
}
@Override
public InputStream getBody() throws IOException {
if (this.body == null) {
this.body = StreamUtils.copyToByteArray(this.response.getBody());
}
return new ByteArrayInputStream(this.body);
}
@Override
public void close() {
this.response.close();
}
}
private final ClientHttpResponse response;
private byte[] body;
ClientHttpResponseWrapper(ClientHttpResponse response) {
this.response = response;
}
@Override
public HttpStatus getStatusCode() throws IOException {
return this.response.getStatusCode();
}
@Override
public int getRawStatusCode() throws IOException {
return this.response.getRawStatusCode();
}
@Override
public String getStatusText() throws IOException {
return this.response.getStatusText();
}
@Override
public HttpHeaders getHeaders() {
return this.response.getHeaders();
}
@Override
public InputStream getBody() throws IOException {
if (this.body == null) {
this.body = StreamUtils.copyToByteArray(this.response.getBody());
}
return new ByteArrayInputStream(this.body);
}
@Override
public void close() {
this.response.close();
}
}
org.springframework.http.client.BufferingClientHttpRequestWrapperをまるコピーです。
あとはこれを下記のように使うだけです。
public class HogeInterceptor implements ClientHttpRequestInterceptor {
@Override
public ClientHttpResponse intercept(final HttpRequest request, final byte[] body, ClientHttpRequestExecution execution) throws IOException{
ClientHttpResponse response = new ClientHttpResponseWrapper(execution.execute(request, body));
~response.getBody()からログを出力する処理~
return response;
}
}
@Override
public ClientHttpResponse intercept(final HttpRequest request, final byte[] body, ClientHttpRequestExecution execution) throws IOException{
ClientHttpResponse response = new ClientHttpResponseWrapper(execution.execute(request, body));
~response.getBody()からログを出力する処理~
return response;
}
}
これでresponseをログ用に読み込んでも落ちなくなります。
まとめ
ログを出したい場面は多いと思うので標準で用意しておいて欲しいな~と思いました。
以上、RestTemplateのClientHttpResponse周りのお話でした。
スポンサーリンク