/*
* URL請求的類別分爲二類,GET與POST請求。二者的區別在於:
* a:) get請求可以獲取靜態頁面,也可以把參數放在URL字串後面,傳遞給servlet,
* b:) post與get的不同之處在於post的參數不是放在URL字串裏面,而是放在http請求的正文內。
*/
URL url = new URL("http://localhost:8080/TestHttpURLConnectionPro.do");
HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
// 設置是否向httpUrlConnection輸出,因爲這個是post請求,參數要放在
// http正文內,因此需要設爲true, 默認情況下是false;
urlConn.setDoOutput(true);
// 設置是否從httpUrlConnection讀入,默認情況下是true;
urlConn.setDoInput(true);
// Post 請求不能使用緩存
urlConn.setUseCaches(false);
// 設定傳送的內容類型是可序列化的java對象
// (如果不設此項,在傳送序列化對象時,當WEB服務默認的不是這種類型時可能拋java.io.EOFException)
urlConn.setRequestProperty("Content-type","application/x-java-serialized-object");
// 設定請求的方法爲"POST",默認是GET
urlConn.setRequestMethod("POST");
// 連接,上面對urlConn的所有配置必須要在connect之前完成,
urlConn.connect();
// 此處getOutputStream會隱含的進行connect (即:如同調用上面的connect()方法,
// 所以在開發中不調用上述的connect()也可以)。
OutputStream outStrm = urlConn.getOutputStream();
// 現在通過輸出流對象構建對象輸出流對象,以實現輸出可序列化的對象。
ObjectOutputStream oos = new ObjectOutputStream(outStrm);
// 向對象輸出流寫出數據,這些數據將存到內存緩衝區中
oos.writeObject(new String("我是測試數據"));
// 刷新對象輸出流,將任何字節都寫入潛在的流中(些處爲ObjectOutputStream)
oos.flush();
// 關閉流對象。此時,不能再向對象輸出流寫入任何數據,先前寫入的數據存在於內存緩衝區中,
// 再調用下邊的getInputStream()函數時才把準備好的http請求正式發送到服務器
oos.close();
// 調用HttpURLConnection連接對象的getInputStream()函數,
// 將內存緩衝區中封裝好的完整的HTTP請求電文發送到服務端。
InputStream inStrm = urlConn.getInputStream(); // <===注意,實際發送請求的代碼段就在這裏
//----------------------------------
/*
* Post傳參的方法
*/
OutputStream os = urlConn.getOutputStream();
String param = new String();
param = "CorpID=123&LoginName=qqq&name=" + URLEncoder.encode("漢字","GBK"); ;
os.write(param.getBytes());
//----------------------------------
/*
* 超時設置,防止 網絡異常的情況下,可能會導致程序僵死而不繼續往下執行
*/
//JDK 1.5以前的版本,只能通過設置這兩個系統屬性來控制網絡超時:
//連接主機的超時時間(單位:毫秒)
System.setProperty("sun.net.client.defaultConnectTimeout", "30000");
//從主機讀取數據的超時時間(單位:毫秒)
System.setProperty("sun.net.client.defaultReadTimeout", "30000");
//在JDK 1.5以後可以這樣來設置超時時間
HttpURLConnection urlCon = (HttpURLConnection)url.openConnection();
urlCon.setConnectTimeout(30000);
urlCon.setReadTimeout(30000);
//----------------------------------
/*
* 總結:
* HttpURLConnection的connect()函數,實際上只是建立了一個與服務器的tcp連接,並沒有實際發送http請求。
* 無論是post還是get,http請求實際上直到HttpURLConnection的getInputStream()這個函數裏面才正式發送出去。
*
* 對HttpURLConnection對象的一切配置都必須要在connect()函數執行之前完成。
* 而對outputStream的寫操作,又必須要在inputStream的讀操作之前。
* 這些順序實際上是由http請求的格式決定的。
*
* 在http頭後面緊跟着的是http請求的正文,正文的內容是通過outputStream流寫入的,
* 實際上outputStream不是一個網絡流,充其量是個字符串流,往裏面寫入的東西不會立即發送到網絡,
* 而是存在於內存緩衝區中,待outputStream流關閉時,根據輸入的內容生成http正文。
* 至此,http請求的東西已經全部準備就緒。在getInputStream()函數調用的時候,就會把準備好的http請求
* 正式發送到服務器了,然後返回一個輸入流,用於讀取服務器對於此次http請求的返回信息。由於http
* 請求在getInputStream的時候已經發送出去了(包括http頭和正文),因此在getInputStream()函數
* 之後對connection對象進行設置(對http頭的信息進行修改)或者寫入outputStream(對正文進行修改)
* 都是沒有意義的了,執行這些操作會導致異常的發生。
*
*/
已測試通過案例,僅供參考:
//url地址,xmlnfo請求Xml報文
public static Map<String,Object> httpPostStrSubMsg(String update_url, String xmlInfo) {
System.out.println("URL="+update_url);
String resp = "";
Map<String,Object> map = new HashMap<String,Object>();
try {
URL url = new URL(update_url);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setDoOutput(true);
con.setRequestProperty("Pragma:", "no-cache");
con.setRequestProperty("Cache-Control", "no-cache");
con.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
con.setRequestMethod("POST");
con.setUseCaches(false);
OutputStreamWriter out = new OutputStreamWriter(con
.getOutputStream(),"utf-8");
out.write(xmlInfo);
out.flush();
out.close();
//接口返回的報文
int code=con.getResponseCode();
String message=con.getResponseMessage();
System.out.println("ResponseCode="+code);
System.out.println("ResponseMessage="+message);
if(code==200){
java.io.BufferedReader breader = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8"));
String str = breader.readLine();
while (str != null) {
resp+=str;
str= breader.readLine();
}
}else{
java.io.BufferedReader breader = new BufferedReader(new InputStreamReader(con.getErrorStream(), "UTF-8"));//獲取錯誤流
String str = breader.readLine();
while (str != null) {
resp+=str;
str= breader.readLine();
}
System.out.println("##更新狀態接口異常,返回報文:"+resp);
}
map.put("code", code);
map.put("data", resp);
} catch (Exception e) {
map.put("code", 911);
map.put("data", e);
e.printStackTrace();
}
return map;
}