在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运行我自己的代码逻辑。