HttpURLConnection的使用

	/*
	 * 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;
	}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章