2016-10-03 87 views
3

我使用以下代碼打印HTTP標頭。HttpURLConnection沒有返回所有標頭

URL url = new Url("htttp://example.com/example"); 
    HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 

    Map<String, List<String>> map = conn.getHeaderFields(); 
    for (Map.Entry<String, List<String>> entry : map.entrySet()) { 
     System.out.println("Key : " + entry.getKey() + 
       " ,Value : " + entry.getValue()); 
    } 

下面是輸出:

Key : null ,Value : [HTTP/1.1 200 OK] 
Key : Accept-Ranges ,Value : [bytes] 
Key : Cache-Control ,Value : [max-age=604800, public] 
Key : Connection ,Value : [Keep-Alive] 
Key : Date ,Value : [Mon, 03 Oct 2016 18:01:06 GMT] 
Key : ETag ,Value : ["159eb4-53dce1f957880-gzip"] 
Key : Expires ,Value : [Mon, 10 Oct 2016 18:01:06 GMT] 
Key : Keep-Alive ,Value : [timeout=5, max=100] 
Key : Last-Modified ,Value : [Sat, 01 Oct 2016 13:59:46 GMT] 
Key : Server ,Value : [Apache/2.4.12 (Unix) OpenSSL/1.0.1e-fips mod_bwlimited/1.4] 
Key : Transfer-Encoding ,Value : [chunked] 
Key : Vary ,Value : [Accept-Encoding,User-Agent] 

現在,我通過捲曲嘗試:

$ curl -v -D - http://example.com/example -o /dev/null 
    % Total % Received % Xferd Average Speed Time Time  Time Current 
           Dload Upload Total Spent Left Speed 
    0  0 0  0 0  0  0  0 --:--:-- --:--:-- --:--:--  0* Trying 111.111.111.111... 
    0  0 0  0 0  0  0  0 --:--:-- 0:00:01 --:--:--  0* Connected to example.com (111.111.111.111) port 80 (#0) 
> GET example.com/example HTTP/1.1 
> Host: example.com 
> User-Agent: curl/7.47.0 
> Accept: */* 
> 
< HTTP/1.1 200 OK 
HTTP/1.1 200 OK 
< Date: Mon, 03 Oct 2016 18:25:11 GMT 
Date: Mon, 03 Oct 2016 18:25:11 GMT 
< Server: Apache/2.4.12 (Unix) OpenSSL/1.0.1e-fips mod_bwlimited/1.4 
Server: Apache/2.4.12 (Unix) OpenSSL/1.0.1e-fips mod_bwlimited/1.4 
< Last-Modified: Sat, 01 Oct 2016 13:59:46 GMT 
Last-Modified: Sat, 01 Oct 2016 13:59:46 GMT 
< ETag: "159eb4-53dce1f957880" 
ETag: "159eb4-53dce1f957880" 
< Accept-Ranges: bytes 
Accept-Ranges: bytes 
< Content-Length: 1416884 
Content-Length: 1416884 
< Cache-Control: max-age=604800, public 
Cache-Control: max-age=604800, public 
< Expires: Mon, 10 Oct 2016 18:25:11 GMT 
Expires: Mon, 10 Oct 2016 18:25:11 GMT 
< Vary: Accept-Encoding,User-Agent 
Vary: Accept-Encoding,User-Agent 

< 
{ [1080 bytes data] 
30 1383k 30 427k 0  0 116k  0 0:00:11 0:00:03 0:00:08 116k^C 

如何看Content-Length頭是Java輸出不見了?爲什麼會發生?我怎樣才能解決這個問題?

+0

它是通過API提供。沒有修復,你不需要一個。 – EJP

+0

@EJP我怎麼不需要修復?如果服務器發送「Content-Length」,API不應該返回「Content-Length」嗎? –

+0

我引用的API是'getContentLength()'(和'getContentLengthLong()')。 – EJP

回答

2

「內容長度」會自動解析,可通過conn.getContentLength()conn.getContentLengthLong()檢索。有關更多信息,請參閱https://docs.oracle.com/javase/7/docs/api/java/net/URLConnection.html#getContentLengthLong()

+0

我沒有解釋爲什麼'content-length'不在頭文件中,如果頭文件不存在,這將返回'-1' –

+0

@NicolasFilotto如果頭文件不是't * sent *,根據curl輸出結果,*不是這裏的情況。 – EJP

+0

@EJP不,我剛剛用curl測試了一下'www.google.com'我發現'Content-Length'是258,但是用java這個頭不是列表的一部分,所以當我調用這個方法時我得到-1 –

4

Content-Length缺失,因爲服務器發送的響應塊。這是預期的行爲。查看Java響應中的Transfer-Encoding標題,這裏是RFC 2616, 4.4 Message Length(請參閱列表中的第3項)。

+0

那麼我該如何禁用? –

+0

@BinoyBabu恐怕這是不可能的。看到這個[相關問題](http://stackoverflow.com/questions/18174435/avoiding-chunked-encoding-of-http-1-1-response)。 [RFC 2616,3.6.1](https://tools.ietf.org/html/rfc2616#section-3.6.1)表示「所有HTTP/1。1應用程序必須能夠接收和解碼「分塊」傳輸編碼,所以我認爲你必須應對這個標題 – nandsito

+0

@BinoyBabu [RFC 2616,14.41](https://tools.ietf.org/ html/rfc2616#section-14.41)表示'很多較舊的HTTP/1.0應用程序不理解Transfer-Encoding標頭',所以如果你可以配置服務器並且真的希望禁用'Transfer-Encoding',你可以將你的服務器退回到HTTP/1.0,但我強烈不鼓勵它,因爲你將失去大部分1.1改進,例如'Transfer-Encoding'本身 – nandsito

0

在java情況下的響應包括在curl響應情況下丟失的'transfer-encoding'頭部。另外,當我嘗試它時,我得到了404(未找到)我的嘗試。當我從我的瀏覽器嘗試時,我也會得到一個404。

我的猜測是,你有一個重寫的主機條目example.com,可以循環回自己的tomcat或類似的。它是你的環境問題。

這就是我得到:

/** 
    * 
    * <P> jdk-1.8 </P> 
    * <PRE> 
Key :null || Values :[HTTP/1.1 404 Not Found] 
Key :X-Cache || Values :[HIT] 
Key :Server || Values :[ECS (ewr/1445)] 
Key :Etag || Values :["359670651+gzip+ident"] 
Key :Cache-Control || Values :[max-age=604800] 
Key :x-ec-custom-error || Values :[1] 
Key :Vary || Values :[Accept-Encoding] 
Key :Last-Modified || Values :[Fri, 09 Aug 2013 23:54:35 GMT] 
Key :Expires || Values :[Mon, 10 Oct 2016 19:20:29 GMT] 
Key :Content-Length || Values :[1270] 
Key :Date || Values :[Mon, 03 Oct 2016 19:20:29 GMT] 
Key :Content-Type || Values :[text/html] 
    * </PRE> 
    * @param urlStr (http://example.com/example) 
    */ 
    private static void printHeaders(String urlStr) { 

     try { 
      URL urlRef = new URL(urlStr); 
      URLConnection urlConnection = urlRef.openConnection(); 
      Map<String, List<String>> headerFields = urlConnection.getHeaderFields(); 

      for (String headerName : headerFields.keySet()) { 
       List<String> headerEntry = headerFields.get(headerName); 
       System.out.println("Key :"+headerName +" || Values :"+headerEntry); 
      } 
     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

    }