0

服務器響應正文爲「[]」,內容長度爲0.當客戶端試圖讀取所提到的響應主體時,它總是一次得到「-1」。另外,如果我攔截服務器響應並將Content-Length更改爲「2」 - 一切正常。我可以得出結論,即當Content-Length = 0時,apache http客戶端返回-1,但實際上響應主體不爲空。即時內容長度不正確,即我可以設置http客戶端忽略內容長度標題值,我正在尋找一種解決方法,以便能夠讀取響應主體?我沒有機會修改服務器,出於某些原因我不能使用HttpUrlConnection而不是Apache客戶端。請提出任何建議。如何在apache http客戶端中忽略零內容長度標頭

回答

1

問題Content-length問題是HttpClient不知道響應何時結束,這也打破了保持連接情況下通過此連接的下一個請求。 最簡單的選擇是擴展org.apache.http.impl.entity.LaxContentLengthStrategy並在頭部爲「0」時返回內容長度「2」,但如果長度爲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/%[email protected]%3E 因爲4.4是相當簡單:

ManagedHttpClientConnectionFactory cliConnFactory = new ManagedHttpClientConnectionFactory(
      null, null, null, 
      new MyLaxContentLengthStrategy()); 

PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(cliConnFactory); 
HttpClients.custom 
..... 
.setConnectionManager(cm) 
.build(); 

所以,如果你其實並不需要具有「[]」的主體,您可以指示HttpClient關閉此連接放棄錯誤的迴應。

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

} 

,你可以這樣設置:這可以通過這樣的重寫org.apache.http.impl.client.DefaultClientConnectionReuseStrategy做

HttpClients.custom 
     ..... 
     .setConnectionReuseStrategy(new MyConnectionReuseStrategy()) 
     .build();