Sal*_*kci 2 java spring http resttemplate
我试图拦截并记录所有请求 - 响应.提出我正在使用的请求RestTemplate.exchange().
当我发出GET请求并得到4**错误时,我可以调用ClientHttpResponse.getBody()并且可以访问响应主体,但for PUT和POSTrequests ClientHttpResponse.getBody()方法会抛出异常.
可能导致这种情况的原因以及我如何获得响应主体POST和PUT请求?
这是我提出请求的地方:
apiResponse = restTemplate.exchange(url, vCloudRequest.getHttpMethod(), entity, responseType);
Run Code Online (Sandbox Code Playgroud)
这是获取异常的拦截器的一部分:
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
ClientHttpResponse response = execution.execute(request, body);
String requestString = new String(body);
String responseString = new
// Below line throws exception
String(ByteStreams.toByteArray(response.getBody()), Charset.forName("UTF-8"));
Run Code Online (Sandbox Code Playgroud)
这是堆栈.
Caused by: java.io.IOException: Server returned HTTP response code: 403 for URL: https://176.235.57.11/api/admin/org/bd154aaf-2e7c-446d-91be-f0a45138476b/users
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1876)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1474)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
at org.springframework.http.client.SimpleClientHttpResponse.getBody(SimpleClientHttpResponse.java:85)
at org.springframework.http.client.BufferingClientHttpResponseWrapper.getBody(BufferingClientHttpResponseWrapper.java:69)
at roma.api_utils.model.Interceptors.RequestLoggingInterceptor.intercept(RequestLoggingInterceptor.java:39)
at org.springframework.http.client.InterceptingClientHttpRequest$InterceptingRequestExecution.execute(InterceptingClientHttpRequest.java:86)
at org.springframework.http.client.InterceptingClientHttpRequest.executeInternal(InterceptingClientHttpRequest.java:70)
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:652)
Run Code Online (Sandbox Code Playgroud)
更新:
当我在打电话response.getStatusCode()之前打电话response.getBody()它不扔IOException.
小智 9
基础知识:
HttpURLConnection有两个相似的字段,errorStream并且inputStream,当我们调用它的getInputSteam方法时,它检查响应是否有错误代码.如此,它会抛出IOException并记录它,这就是你得到异常的原因;此外,它还将内容复制inputStream到errorStream因此我们可以通过调用它的getErrorStream方法来获取它的响应体,这正是SimpleClientHttpResponse对其getBody方法的作用:
@Override
public InputStream getBody() throws IOException {
InputStream errorStream = this.connection.getErrorStream();
this.responseStream =
(errorStream != null ? errorStream : this.connection.getInputStream());
return this.responseStream;
}
Run Code Online (Sandbox Code Playgroud)
它首先检查if是否errorStream为null,如果为false,则返回它,如果为true,则调用connection.getInputStream()并返回
现在就是答案
response.getBody()不抛出IOException你叫后response.getStatusCode(),这是因为getStatusCode电话getInputStreaminternally.Thus,errorStream将不为空时getBody被调用org.springframework.http.client.SimpleBufferingClientHttpRequest#executeInternal..
@Override
protected ClientHttpResponse executeInternal(HttpHeaders headers, byte[] bufferedOutput)
throws IOException {
addHeaders(this.connection, headers);
// JDK <1.8 doesn't support getOutputStream with HTTP DELETE
if (HttpMethod.DELETE == getMethod() && bufferedOutput.length == 0) {
this.connection.setDoOutput(false);
}
if (this.connection.getDoOutput() && this.outputStreaming) {
this.connection.setFixedLengthStreamingMode(bufferedOutput.length);
}
this.connection.connect();
if (this.connection.getDoOutput()) {
FileCopyUtils.copy(bufferedOutput, this.connection.getOutputStream());
}
else {
// Immediately trigger the request in a no-output scenario as well
this.connection.getResponseCode();
}
return new SimpleClientHttpResponse(this.connection);
}
Run Code Online (Sandbox Code Playgroud)
this.connection.getResponseCode();当http方法是GET时, 它急切地执行
| 归档时间: |
|
| 查看次数: |
2342 次 |
| 最近记录: |