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。