服务器响应正文是" []"并且Content-Length = 0.当客户端试图读取提到的响应体时,它总是一次得到" -1"。此外,如果我拦截服务器响应并将内容长度更改为" 2" - 一切正常。我可以得出结论,当Content-Length = 0时,apache http客户端返回-1,但实际上响应体不为空。我正在寻找一种解决方法,即使Content-length不正确也能读取响应正文,即我可以设置http客户端忽略Content-length头值吗?我没有机会修改服务器,出于某些原因我不能使用HttpUrlConnection代替apache客户端。请提出任何建议。
答案 0 :(得分:1)
错误Content-length
的问题是HttpClient不知道响应何时结束,这也会在Keep-Alive连接的情况下中断此连接的下一个请求。
最简单的选择是扩展org.apache.http.impl.entity.LaxContentLengthStrategy并使其在标题中返回内容长度为“2”时为“0”,但如果长度为0,则线程将挂起等待读取更多来自插座:
class MyLaxContentLengthStrategy extends LaxContentLengthStrategy{
public long determineLength(final HttpMessage message) throws HttpException {
final Header contentLengthHeader = message.getFirstHeader(HTTP.CONTENT_LEN);
if (contentLengthHeader != null) {
long contentlen = -1;
final Header[] headers = message.getHeaders(HTTP.CONTENT_LEN);
for (int i = headers.length - 1; i >= 0; i--) {
final Header header = headers[i];
try {
contentlen = Long.parseLong(header.getValue());
break;
} catch (final NumberFormatException ignore) {
}
// See if we can have better luck with another header, if present
}
if (contentlen == 0) {
return 2;
}
}
return super.determineLength(message);
}
}
在HttpClient中设置哪个可能有点棘手: http://mail-archives.apache.org/mod_mbox/hc-httpclient-users/201301.mbox/%3C1359388867.10617.16.camel@ubuntu%3E 从4.4开始就很容易了:
ManagedHttpClientConnectionFactory cliConnFactory = new ManagedHttpClientConnectionFactory(
null, null, null,
new MyLaxContentLengthStrategy());
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(cliConnFactory);
HttpClients.custom
.....
.setConnectionManager(cm)
.build();
因此,如果您实际上不需要带有“[]”的正文,则可以指示HttpClient关闭此连接并放弃错误的响应。这可以通过使用以下内容覆盖org.apache.http.impl.client.DefaultClientConnectionReuseStrategy来完成:
class MyConnectionReuseStrategy extends DefaultClientConnectionReuseStrategy{
@Override
public boolean keepAlive(final HttpResponse response, final HttpContext context) {
final HttpRequest request = (HttpRequest) context.getAttribute(HttpCoreContext.HTTP_REQUEST);
if (request != null) {
final Header[] contLenHeaders = request.getHeaders(HttpHeaders.CONTENT_LENGTH);
for(Header h : contLenHeaders){
if("0".equalsIgnoreCase(h.getValue())){
return false;
}
}
}
return super.keepAlive(response, context);
}
}
您可以这样设置:
HttpClients.custom
.....
.setConnectionReuseStrategy(new MyConnectionReuseStrategy())
.build();