HttpURLConnection 411錯誤解決


1.問題描述

Java HttpURLConnection類發送Http請求鏈接外網返回ResponseCode為411,對方為.NET服務器,網上查明原因可能來自以下:

1、可能是沒有傳http中的content-length參數,這個一般都有。
2、可能是因為請求方式錯誤的,本來只是獲取數據,應該使用GET的方式;但是你使用的是POST的方式。

首先第一個方法:

conn.setRequestProperty("Content-Length", ""+info.getBytes().length);

設置后還是411錯誤

第二個方法:將請求方式改為GET, 成功。

但聯調方反饋請求方式沒有變,依然為POST,很納悶.....下班后,用瀏覽器Http在線測試工具試了一下,發現添加參數Content-Length后,POST方式也能請求成功。

反過來,打印日志,發現屬性"Content-Length"為NULL...也就是HTTPURLConnection調用setRequestProperty無效。所以這里也提醒自己,自測萬無一失能避免溝通浪費。

這里推薦http測試用fiddler。定位到問題就好查了。

http://blog.csdn.net/Feng______/article/details/38301293 這個人總結的很好,自己也去看了源碼。

 private static final Set<String> restrictedHeaderSet;
    private static final String[] restrictedHeaders = {
	/* Restricted by XMLHttpRequest2 */
	//"Accept-Charset",
	//"Accept-Encoding",
	"Access-Control-Request-Headers",
	"Access-Control-Request-Method",
	"Connection", /* close is allowed */
	"Content-Length",
	//"Cookie",
	//"Cookie2",
	"Content-Transfer-Encoding",
	//"Date",
	"Expect",
	"Host",
	"Keep-Alive",
	"Origin",
	// "Referer", 
	// "TE",
	"Trailer",
	"Transfer-Encoding",
	"Upgrade",
	//"User-Agent",
	"Via"
    };

在靜態初始化代碼中發現allowRestrictedHeaders是由安全管理器的返回值決定的。

restrictedHeaderSet的內容是由restrictedHeaders數組決定的。

大概原因就是出於安全考慮,這些字段盡量不要被改動。sun就做了這一套安全機制。

解決方法是在JVM啟動時加入sun.NET.http.allowRestrictedHeaders屬性為true。

First, the order of the headers is irrelevant.
Second, in order to manually override the host header you need to set sun.net.http.allowRestrictedHeaders=trueeither in code

直接在程序里面加下面代碼。然后就OK了。

System.setProperty("sun.net.http.allowRestrictedHeaders", "true");

HttpURLConnection接口

http://www.cjsdn.net/doc/jdk50/java/net/HttpURLConnection.html

http://www.cnblogs.com/skyaccross/archive/2012/12/22/2828986.html

 

2. DoOutput和DoInput說明

httpUrlConnection.setDoOutput(true)

httpUrlConnection.setDoInput(true)

這兩個方法在develope的httpUrlConnection方法中找不到的。

get請求用不到conn.getOutputStream(),因為參數直接追加在地址后面,因此默認是false。

post請求(比如:文件上傳)需要往服務區傳輸大量的數據,這些數據是放在http的body里面的,因此需要在建立連接以后,往服務端寫數據。  

因為總是使用conn.getInputStream()獲取服務端的響應,因此默認值是true。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM