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。
