HttpClient的使用 – Android移動開發技術文章_手機開發 Android移動開發教學課程

HTTP 協議可能是現在 Internet 上使用得最多、最重要的協議瞭,越來越多的 Java 應用程序需要直接通過 HTTP 協議來訪問網絡資源。
http的主要功能包括:
1. 實現瞭所有 HTTP 的方法(GET,POST,PUT,HEAD 等)
2. 支持自動轉向
3. 支持 HTTPS 協議
4. 支持代理服務器等
使用 HttpClient 需要以下 6 個步驟:
1. 創建 HttpClient 的實例
2. 創建某種連接方法的實例,在這裡是 GetMethod。在 GetMethod 的構造函數中傳入待連接的地址
3. 調用第一步中創建好的實例的 execute 方法來執行第二步中創建好的 method 實例
4. 讀 response
5. 釋放連接。無論執行方法是否成功,都必須釋放連接
6. 對得到後的內容進行處理
 
根據以上步驟,我們來編寫用GET方法來取得某網頁內容的代碼。
大部分情況下 HttpClient 默認的構造函數已經足夠使用。
HttpClient httpClient = new HttpClient();
創建GET方法的實例。在GET方法的構造函數中傳入待連接的地址即可。用GetMethod將會自動處理轉發過程,如果想要把自動處理轉發過程去掉的話,可以調用方法setFollowRedirects(false)。
GetMethod getMethod = new GetMethod(http://www.ibm.com/);
調用實例httpClient的executeMethod方法來執行getMethod。由於是執行在網絡上的程序,在運行executeMethod方法的時候,需要處理兩個異常,分別是HttpException和IOException。引起第一種異常的原因主要可能是在構造getMethod的時候傳入的協議不對,比如不小心將"http"寫成"htp",或者服務器端返回的內容不正常等,並且該異常發生是不可恢復的;第二種異常一般是由於網絡原因引起的異常,對於這種異常 (IOException),HttpClient會根據你指定的恢復策略自動試著重新執行executeMethod方法。HttpClient的恢復策略可以自定義(通過實現接口HttpMethodRetryHandler來實現)。通過httpClient的方法setParameter設置你實現的恢復策略,本文中使用的是系統提供的默認恢復策略,該策略在碰到第二類異常的時候將自動重試3次。executeMethod返回值是一個整數,表示瞭執行該方法後服務器返回的狀態碼,該狀態碼能表示出該方法執行是否成功、需要認證或者頁面發生瞭跳轉(默認狀態下GetMethod的實例是自動處理跳轉的)等。
 
Java代碼 
//設置成瞭默認的恢復策略,在發生異常時候將自動重試3次,在這裡你也可以設置成自定義的恢復策略   
getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,    
        new DefaultHttpMethodRetryHandler());    
//執行getMethod   
int statusCode = client.executeMethod(getMethod);   
if (statusCode != HttpStatus.SC_OK) {   
  System.err.println("Method failed: " + getMethod.getStatusLine());   
}   
//設置成瞭默認的恢復策略,在發生異常時候將自動重試3次,在這裡你也可以設置成自定義的恢復策略 
getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,  
        new DefaultHttpMethodRetryHandler());  
//執行getMethod 
int statusCode = client.executeMethod(getMethod); 
if (statusCode != HttpStatus.SC_OK) { 
  System.err.println("Method failed: " + getMethod.getStatusLine()); 
}  
  
 
在返回的狀態碼正確後,即可取得內容。取得目標地址的內容有三種方法:第一種,getResponseBody,該方法返回的是目標的二進制的byte流;第二種,getResponseBodyAsString,這個方法返回的是String類型,值得註意的是該方法返回的String的編碼是根據系統默認的編碼方式,所以返回的String值可能編碼類型有誤,在本文的"字符編碼"部分中將對此做詳細介紹;第三種,getResponseBodyAsStream,這個方法對於目標地址中有大量數據需要傳輸是最佳的。在這裡我們使用瞭最簡單的getResponseBody方法。
釋放連接。無論執行方法是否成功,都必須釋放連接。
method.releaseConnection();

處理內容。在這一步中根據你的需要處理內容,在例子中隻是簡單的將內容打印到控制臺。
System.out.println(new String(responseBody));

完整的代碼示例
Java代碼 
public class FeedBackServiceImpl implements FeedBackService, InitializingBean { 
    private static final Logger log = LoggerFactory.getLogger(FeedBackServiceImpl.class); 
 
    private static final int    CONNECTION_TIME_OUT      = 1000; 
    private static final int    TIME_OUT                 = 2000; 
    /**
     * 參數
     */ 
    private static final String PARAM_ID                 = "id"; 
    private static final String PARAM_QUESTION_ID        = "questionId"; 
    private static final String PARAM_ANSWER             = "answer"; 
    private static final String PARAM_COOKIE_ID          = "cookieId"; 
 
    /**
     * 蓋婭系統獲取調查問卷的url
     */ 
    private String              feedBackQuestionaireUrl; 
    /**
     * 蓋婭系統保存用戶反饋信息的url
     */ 
    private String              feedBackAnswerUrl; 
    /**
     * 問卷類型與問卷id的映射
     * 
     * <pre>
     * 問卷類型,從前臺傳遞過來。目前有兩個取值:"1"表示進貨單頁面的問卷;"2"表示確認訂單頁面的問卷
     * 問卷id,作為從蓋婭系統中獲取調查問卷的參數
     * </pre>
     */ 
    private Map<String, String> questionTypeToQuestionId = new HashMap<String, String>(); 
 
    private HttpClient          httpClient; 
 
    public boolean addFeedBack(FeedBackModel feedBackModel) { 
        if (feedBackModel == null) { 
            return false; 
        } 
        boolean res = false; 
        // 調用蓋婭系統的接口,提交反饋 
        PostMethod postMethod = new PostMethod(feedBackAnswerUrl); 
        postMethod.addParameter(PARAM_QUESTION_ID, feedBackModel.getQuestionId()); 
        postMethod.addParameter(PARAM_ANSWER, feedBackModel.getAnswer()); 
        postMethod.addParameter(PARAM_COOKIE_ID, feedBackModel.getCookieId()); 
        try { 
            int statusCode = httpClient.executeMethod(postMethod); 
            if (statusCode != HttpStatus.SC_OK) { 
                StringBuilder sb = new StringBuilder("fail to add feedback, requestUrl="); 
                sb.append(feedBackAnswerUrl).append(", parameter: ").append(feedBackModel.toString()).append(", HTTP StatusCode=").append(statusCode); 
                log.error(sb.toString()); 
                res = false; 
            } else { 
                res = true; 
            } 
        } catch (HttpException e) { 
            log.error("HttpException occured when addFeedBack, requestUrl=" + feedBackAnswerUrl + ", parameter: " + feedBackModel.toString(), e); 
            res = false; 
        } catch (IOException e) { 
            log.error("IOException occured when addFeedBack, requestUrl=" + feedBackAnswerUrl + ", parameter: " + feedBackModel.toString(), e); 
            res = false; 
        } finally { 
            postMethod.releaseConnection(); 
            postMethod = null; 
        } 
        return res; 
    } 
 
    public JSONObject getQuestionaire(String questionType) { 
        String id = questionTypeToQuestionId.get(questionType); 
        if (StringUtil.isBlank(id)) { 
            return null; 
        } 
         
        // 調用蓋婭系統的接口,獲取調查問卷 
        GetMethod getMethod = new GetMethod(feedBackQuestionaireUrl); 
        NameValuePair param = new NameValuePair(PARAM_ID, id); 
        getMethod.setQueryString(new NameValuePair[]{param}); 
        String responseText = null; 
        try { 
            // 執行getMethod 
            int statusCode = httpClient.executeMethod(getMethod); 
            if (statusCode != HttpStatus.SC_OK) { 
                StringBuilder sb = new StringBuilder("fail to getQuestionaire, requestUrl="); 
                sb.append(feedBackQuestionaireUrl).append("?id=").append(id).append(", HTTP StatusCode=").append(statusCode); 
                log.error(sb.toString()); 
                return null; 
            } 
            // 讀取內容 
            responseText = getMethod.getResponseBodyAsString(); 
        } catch (HttpException e) { 
            StringBuilder sb = new StringBuilder("HttpException occured when getQuestionaire, requestUrl="); 
            sb.append(feedBackQuestionaireUrl).append("?id=").append(id); 
            log.error(sb.toString(), e); 
            return null; 
        } catch (IOException e) { 
            StringBuilder sb = new StringBuilder("IOException occured when getQuestionaire, requestUrl="); 
            sb.append(feedBackQuestionaireUrl).append("?id=").append(id); 
            log.error(sb.toString(), e); 
            return null; 
        } finally { 
            getMethod.releaseConnection(); 
            getMethod = null; 
        } 
         
        if (StringUtil.isBlank(responseText)) { 
            return null; 
        } 
         
        // 從查詢結果中解析出包含問卷的json字符串 
        int index = responseText.indexOf("="); 
        if (index >= 0) { 
            responseText = responseText.substring(index + 1); 
        } 
        try { 
            JSONObject json = JSONObject.fromObject(responseText); 
            return json; 
        } catch (Exception e) { 
            log.error("fail to change from String to JSONObject, string=" + responseText, e); 
            return null; 
        } 
    } 
     
    public void afterPropertiesSet() throws Exception { 
        HttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager(); 
        httpClient = new HttpClient(connectionManager); 
        httpClient.setConnectionTimeout(CONNECTION_TIME_OUT); 
        httpClient.setTimeout(TIME_OUT); 
    } 

作者“hwy584624785”
 

發佈留言