1. 程式人生 > >Pro Android學習筆記(六九):HTTP服務(3):HTTP POST MultiPart

Pro Android學習筆記(六九):HTTP服務(3):HTTP POST MultiPart

HTTP POST不僅可以通過鍵值對傳遞引數,還可以攜帶更為複雜的引數,例如檔案。HTTP Post支援攜帶body,content-type為multipart。本次我們將嘗試通過http post上傳一個小檔案。

建立測試環境

上傳檔案的測試環境很難找,下載了Tomcat,想裝一個環境,開啟後,發現忘得也差不多,要看幫助,比較麻煩,下面是我上傳檔案到189網盤抓的包,上傳一個圖片檔案,整個content長度為39K。網盤很難作為測試環境的原因是,我們必須完成登入等一系列操作。我們只是需要驗證一下小例子,可以簡單通過抓包來判斷,預計web server會返回4xx或5xx的錯誤,但這不影響我們的實驗。

開發環境:匯入第三方JAR

在以前的ADT版本中,可以在相應的Project按右鍵,參見Android學習筆記(四四):第三方Java庫的使用。選擇Properties,進去後選擇Java Build Path,然後選擇Libaraies,點選Add External JARs就新增。但是在最新的版本中,採用這種方式在編譯中正常,在執行時會報NoClassDefFoundError,如下。

原因是,這些Jar包並沒有真正打入apk中。在新的ADT,我們直接將相應的jar包拷貝到project下面的libs/的目錄,然後在Eclipse中點選libs/,按右鍵,選擇重新整理即可。我們在libs/和Android Private Libraries/中都可以看到相應的jar,如下圖所示:

如果我們匯入的是最新httpmime-4.3.1.jar,需要將httpcore-4.3.jar同時匯入,在接下來的程式碼編寫使用到InputStreamBody資料型別,InputStreamBody會使用到httpcore的類,否者執行時會報org.apache.http.entity.ContentType cannot be resolved的錯誤。

HTTP Post Multipart小例子

HTTP Post Multipart也是HTTP Post的例子,和之前的小例子相比,只是設定HTTP引數不同,本例子將設定multipart引數。下面截去例子中的部分,如何讀response與之前的相同,不再重複。

private HttpResponse multiPartTest() throws Exception{ 
    try{             
        HttpClient client = new DefaultHttpClient(); 
        HttpPost request = new HttpPost("http://upload.cloud.189.cn/v5/v5webUploadSmallFileActionl");
 
            
        //設定HTTP引數,本例設定Multipart引數 
        //(1)上傳檔案readme.txt已經放在asset/下,獲取該檔案的ContentBody。如果是在存貯中某個目錄下,可以用FileBody fb = new FileBody(File f)來得到該ContentBody。
        InputStream is = this.getAssets().open("readme.txt"); 
        byte[] data = IOUtils.toByteArray(is);               
        InputStreamBody isb = new InputStreamBody(new ByteArrayInputStream(data), "myUpload");               
        //(2)除了檔案外,我們再附加兩個引數,生成這兩個引數的ContentBody
        StringBody sb1 = new StringBody("some text goes here"); 
        StringBody sb2 = new StringBody("some text goes here, too"); 
       //(3)作為multipart引數,加入到request中
        MultipartEntity multiEntity = new MultipartEntity(); 
        multiEntity.addPart("myUpload", isb);    
        multiEntity.addPart("one",sb1); 
        multiEntity.addPart("two",sb2);              
        request.setEntity(multiEntity); 
//在上個例子中setEntity()裡的引數是UrlEncodedFormEntity本次是MultiPartEntity
              
        return client.execute(request);               
    }catch(Exception e){ 
        throw e; 
    } 
}

回頭說說調測環境,我們在網上找來一個http server,本例是189網盤,向其傳送http post multipart請求,由於我們沒有進行網盤使用者登入的過程,而引數也非189所指定,因此收到到404訊息的reponse。但我們可以通過抓包工具來檢視各引數的填入情況,來了解如何在Android中填構multipart。本例我們在multipart entity中加了三個引數,讓我們看看request包。

如果我們在機器上狀態tomcat apache來搭建測試環境,需要注意的是在模擬器中不能使用127.0.0.1來指向機器的tomcat server,那會指向模擬器本身,要使用網絡卡的地址。