0

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

1

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();