1

RestTemplate クラスの doExecute() 内には、次のコードがあります。

        ...
        response = request.execute();
        if (!getErrorHandler().hasError(response)) {
            logResponseStatus(method, url, response);
        }
        else {
            handleResponseError(method, url, response);
        }
        if (responseExtractor != null) {
            return responseExtractor.extractData(response);
        }
        else {
            return null;
        }
        ...

OAuth2RestTemplate を使用する場合、ResponseErrorHandler は OAuth2ErrorHandler に設定されます。私の特定のユースケースでは、(oauth トークンを取得した後の) リクエストは、コード内で処理したい 400 エラーを返しています。そのため、何もしないように DefaultResponseHandler.handleError() をオーバーライドするカスタム ハンドラーを渡して OAuth2ErrorHandler を作成しました。これにより、RestTemplate.postForEntity() を呼び出すコードが ResponseEntity を取得できるようになり、それに対してさらに評価を行うことができます。

今私が見ている問題は、上記のコードの handleResponseError 内で、それが OAuth2ErrorHandler.handleError() に入り、そのコード内に次の注意事項があることです。

        ...
        // Need to use buffered response because input stream may need to be consumed multiple times.
        ClientHttpResponse bufferedResponse = new ClientHttpResponse() {
        ...

これは、OAuth2ErrorHandler がデリゲート errorHandler を呼び出したときにうまく機能します。これは、errorHandler が応答も読み取ることができるためです。残念ながら、そのメソッドが bufferedResponse を返すと、もはや利用できず、 responseExtractor.extractData(response) が呼び出されると、入力ストリームが閉じられます。

私が見ている例外は次のとおりです。

Caused by: org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Attempted read from closed stream.; nested exception is java.io.IOException: Attempted read from closed stream.
    at org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.readJavaType(MappingJackson2HttpMessageConverter.java:228)
    at org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.read(MappingJackson2HttpMessageConverter.java:220)
    at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:95)
    at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:788)
    at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:773)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:553)
    at org.springframework.security.oauth2.client.OAuth2RestTemplate.doExecute(OAuth2RestTemplate.java:128)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:506)
    at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:361)
Caused by: java.io.IOException: Attempted read from closed stream.
    at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:167)
    at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:137)
    at com.fasterxml.jackson.core.json.ByteSourceJsonBootstrapper.ensureLoaded(ByteSourceJsonBootstrapper.java:503)
    at com.fasterxml.jackson.core.json.ByteSourceJsonBootstrapper.detectEncoding(ByteSourceJsonBootstrapper.java:129)
    at com.fasterxml.jackson.core.json.ByteSourceJsonBootstrapper.constructParser(ByteSourceJsonBootstrapper.java:224)
    at com.fasterxml.jackson.core.JsonFactory._createParser(JsonFactory.java:1242)
    at com.fasterxml.jackson.core.JsonFactory.createParser(JsonFactory.java:753)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2158)
    at org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.readJavaType(MappingJackson2HttpMessageConverter.java:225)
    ... 31 common frames omitted

この問題を回避する方法はありますか? 私のユース ケースでは、OAuth2RestTemplate を使用して OAuth ハンドシェイクを処理し、ResponseEntity に対して独自のコード ロジックを実行できるようにしたいと考えています。

4

0 に答える 0