作者:Tony_Friday | 来源:互联网 | 2023-06-15 09:22
Spring RestTemplate返回的getBody为null问题
- Spring RestTemplate请求返回的body内容为null
Spring RestTemplate请求返回的body内容为null
1.最近在项目中遇到一个问题就是,我准备用Spring中自带的工具进行请求的对方接口的时候。在测试环境没有任何问题,但是在调用对方的登陆接口的时候,对方接口返回了json数据,但是我通过一下方法拿到数据始终为null
ResponseEntity forEntity = restTemplate.postForEntity(url,formEntity, String.class);
System.out.println(forEntity.getBody());
//返回为null
起初我以为对方接口的问题.通过PostMan进行访问对方接口的时候,却能够正确返回json数据.然后通过打印底层的HttpClient的日志的时候发现,确实里面返回了数据。那到底是怎么回事呢?于是就猜测是不是RestTemplate的问题。经过不断的断点跟踪,发现了RestTemplate在处理返回的json数据的时候,是根据header中的一个Content-length判断是否有数据,恰好对方接口的返回了数据,但是这个参数为0.具体的源代码在:
RestTemplate中的
@Nullable
protected T doExecute(URI url, @Nullable HttpMethod method, @Nullable RequestCallback requestCallback,
@Nullable ResponseExtractor responseExtractor) throws RestClientException {
Assert.notNull(url, "'url' must not be null");
Assert.notNull(method, "'method' must not be null");
ClientHttpResponse respOnse= null;
try {
ClientHttpRequest request = createRequest(url, method);
if (requestCallback != null) {
requestCallback.doWithRequest(request);
}
respOnse= request.execute();
//跟踪返回的结果,这里是在处理返回的结果
handleResponse(url, method, response);
if (responseExtractor != null) {
return responseExtractor.extractData(response);
}
else {
return null;
}
}
catch (IOException ex) {
String resource = url.toString();
String query = url.getRawQuery();
resource = (query != null ? resource.substring(0, resource.indexOf('?')) : resource);
throw new ResourceAccessException("I/O error on " + method.name() +
" request for "" + resource + "": " + ex.getMessage(), ex);
}
finally {
if (response != null) {
response.close();
}
}
}
里面的这个方法是在处理结果:
@Override
public ResponseEntity extractData(ClientHttpResponse response) throws IOException {
if (this.delegate != null) {
T body = this.delegate.extractData(response);
return ResponseEntity.status(response.getRawStatusCode()).headers(response.getHeaders()).body(body);
}
else {
return ResponseEntity.status(response.getRawStatusCode()).headers(response.getHeaders()).build();
}
}
}
MessageBodyClientHttpResponseWrapper中获取了Content-length的长度判断是否有数据。
public boolean hasMessageBody() throws IOException {
HttpStatus status = HttpStatus.resolve(getRawStatusCode());
if (status != null && (status.is1xxInformational() || status == HttpStatus.NO_CONTENT ||
status == HttpStatus.NOT_MODIFIED)) {
return false;
}
//这里判断为0就直接返回false。实际上是有数据的
if (getHeaders().getContentLength() == 0) {
return false;
}
return true;
}
PostMan请求结果也看到Content-length为0
后面我换成HttpClient方式就能解决了这个问题,具体原因还没有去深入研究。但是这个参数看网上都说Conent-length代表了body的大小。有知道的大神告诉一下。