Die Server-Antwort Körper ist "[]" und die Content-Length = 0. Wenn Client versucht, erwähnte Antwort Körper gelesen wird es immer einmal "-1". Wenn ich die Server-Antwort abfange und die Inhaltslänge auf "2" ändere, funktioniert alles. Ich kann Schlussfolgerung machen, dass Apache HTTP-Client -1 zurückgibt, wenn Content-Length = 0, aber der Antworttextkörper tatsächlich nicht leer ist. Ich suche nach einer Problemumgehung, Antwortkörper lesen zu können, selbst wenn die Inhaltslänge falsch ist, d. H. Kann ich HTTP-Client einrichten, um den Inhalt-Länge-Header-Wert zu ignorieren? Ich habe keine Chance, Server zu ändern, und ich kann HttpUrConnection statt Apache-Client aus einigen Gründen nicht verwenden. Bitte, jeden Vorschlag.Wie ignorieren Null Inhalt Länge Header in Apache HTTP-Client
Antwort
Das Problem mit fehlerhaften Content-length
ist, dass HttpClient nicht weiß, wenn die Antwort vorbei ist, dies bricht auch die nächste Anfrage über diese Verbindung im Falle Keep-Alive-Verbindung. Die einfachste Option besteht darin, org.apache.http.impl.entity.LaxContentLengthStrategy zu erweitern und die Inhaltslänge "2" zurückzugeben, wenn sie im Header "0" ist, aber wenn die Länge wirklich 0 ist, wartet der Thread darauf lesen Sie mehr aus der Fassung:
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);
}
}
Rahmen, von denen in der Httpclient ein wenig sein könnte heikel: http://mail-archives.apache.org/mod_mbox/hc-httpclient-users/201301.mbox/%[email protected]%3E Seit 4.4 ist es ganz einfach:
ManagedHttpClientConnectionFactory cliConnFactory = new ManagedHttpClientConnectionFactory(
null, null, null,
new MyLaxContentLengthStrategy());
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(cliConnFactory);
HttpClients.custom
.....
.setConnectionManager(cm)
.build();
Also, wenn Sie eigentlich nicht brauchen nicht der Körper mit "[]", können Sie den HttpClient anweisen, diese Verbindung zu schließen a nd geben die fehlerhafte Antwort auf. Dies kann durch Überschreiben der org.apache.http.impl.client.DefaultClientConnectionReuseStrategy mit so etwas wie dies geschehen:
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);
}
}
, die Sie mögen diese einstellen:
HttpClients.custom
.....
.setConnectionReuseStrategy(new MyConnectionReuseStrategy())
.build();