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 错误,我想在我的代码中处理该错误。因此,我通过传入我的自定义处理程序来创建 OAuth2ErrorHandler,该处理程序覆盖 DefaultResponseHandler.handleError() 什么都不做。这将允许调用 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