1. 程式人生 > >Android模擬 HTTP multipart/form-data 請求協議資訊實現圖片上傳

Android模擬 HTTP multipart/form-data 請求協議資訊實現圖片上傳

轉自:http://www.linuxidc.com/Linux/2011-08/41944.htm

問題:

Android應用中,當遇到填寫使用者資訊、發表評論等操作,不可避免會遇到“form表單操作”(類似web form操作)上傳圖片的功能。

在這種情況下,使用Android的HTTPConnection/ ApacheHTTP 通過POST 和GET的方式就實現不了。

解決方法:

Android客戶端通過模擬 HTTP multipart/form-data 請求協議資訊實現圖片上傳。

  1. /**
  2. *檔名稱:UploadImage.java
  3. *
  4. *版權資訊:ApacheLicense,Version2.0
  5. *
  6. *功能描述:實現圖片檔案上傳。
  7. *
  8. *建立日期:2011-5-10
  9. *
  10. *作者:BertLee
  11. */
  12. /*
  13. *修改歷史:
  14. */
  15. publicclassUploadImage{
  16. Stringmultipart_form_data="multipart/form-data";
  17. StringtwoHyphens="--";
  18. Stringboundary="****************fD4fH3gL0hK7aI6";//資料分隔符
  19. StringlineEnd=System.getProperty("line.separator");//Thevalueis"\r\n"inWindows.
  20. /*
  21. *上傳圖片內容,格式請參考HTTP協議格式。
  22. *人人網Photos.upload中的”程式呼叫“http://wiki.dev.renren.com/wiki/Photos.upload#.E7.A8.8B.E5.BA.8F.E8.B0.83.E7.94.A8
  23. *對其格式解釋的非常清晰。
  24. *格式如下所示:
  25. *--****************fD4fH3hK7aI6
  26. *Content-Disposition:form-data;name="upload_file";filename="apple.jpg"
  27. *Content-Type:image/jpeg
  28. *
  29. *這兒是檔案的內容,二進位制流的形式
  30. */
  31. privatevoidaddImageContent(Image[]files,DataOutputStreamoutput){
  32. for(Imagefile:files){
  33. StringBuildersplit=newStringBuilder();
  34. split.append(twoHyphens+boundary+lineEnd);
  35. split.append("Content-Disposition:form-data;name=\""+file.getFormName()+"\";filename=\""+file.getFileName()+"\""+lineEnd);
  36. split.append("Content-Type:"+file.getContentType()+lineEnd);
  37. split.append(lineEnd);
  38. try{
  39. //傳送圖片資料
  40. output.writeBytes(split.toString());
  41. output.write(file.getData(),0,file.getData().length);
  42. output.writeBytes(lineEnd);
  43. }catch(IOExceptione){
  44. thrownewRuntimeException(e);
  45. }
  46. }
  47. }
  48. /*
  49. *構建表單欄位內容,格式請參考HTTP協議格式(用FireBug可以抓取到相關資料)。(以便上傳表單相對應的引數值)
  50. *格式如下所示:
  51. *--****************fD4fH3hK7aI6
  52. *Content-Disposition:form-data;name="action"
  53. *//一空行,必須有
  54. *upload
  55. */
  56. privatevoidaddFormField(Set<Map.Entry<Object,Object>>params,DataOutputStreamoutput){
  57. StringBuildersb=newStringBuilder();
  58. for(Map.Entry<Object,Object>param:params){
  59. sb.append(twoHyphens+boundary+lineEnd);
  60. sb.append("Content-Disposition:form-data;name=\""+param.getKey()+"\""+lineEnd);
  61. sb.append(lineEnd);
  62. sb.append(param.getValue()+lineEnd);
  63. }
  64. try{
  65. output.writeBytes(sb.toString());//傳送表單欄位資料
  66. }catch(IOExceptione){
  67. thrownewRuntimeException(e);
  68. }
  69. }
  70. /**
  71. *直接通過HTTP協議提交資料到伺服器,實現表單提交功能。
  72. *@paramactionUrl上傳路徑
  73. *@paramparams請求引數key為引數名,value為引數值
  74. *@paramfiles上傳檔案資訊
  75. *@return返回請求結果
  76. */
  77. publicStringpost(StringactionUrl,Set<Map.Entry<Object,Object>>params,Image[]files){
  78. HttpURLConnectionconn=null;
  79. DataOutputStreamoutput=null;
  80. BufferedReaderinput=null;
  81. try{
  82. URLurl=newURL(actionUrl);
  83. conn=(HttpURLConnection)url.openConnection();
  84. conn.setConnectTimeout(120000);
  85. conn.setDoInput(true);//允許輸入
  86. conn.setDoOutput(true);//允許輸出
  87. conn.setUseCaches(false);//不使用Cache
  88. conn.setRequestMethod("POST");
  89. conn.setRequestProperty("Connection","keep-alive");
  90. conn.setRequestProperty("Content-Type",multipart_form_data+";boundary="+boundary);
  91. conn.connect();
  92. output=newDataOutputStream(conn.getOutputStream());
  93. addImageContent(files,output);//新增圖片內容
  94. addFormField(params,output);//新增表單欄位內容
  95. output.writeBytes(twoHyphens+boundary+twoHyphens+lineEnd);//資料結束標誌
  96. output.flush();
  97. intcode=conn.getResponseCode();
  98. if(code!=200){
  99. thrownewRuntimeException("請求‘"+actionUrl+"’失敗!");
  100. }
  101. input=newBufferedReader(newInputStreamReader(conn.getInputStream()));
  102. StringBuilderresponse=newStringBuilder();
  103. StringoneLine;
  104. while((oneLine=input.readLine())!=null){
  105. response.append(oneLine+lineEnd);
  106. }
  107. returnresponse.toString();
  108. }catch(IOExceptione){
  109. thrownewRuntimeException(e);
  110. }finally{
  111. //統一釋放資源
  112. try{
  113. if(output!=null){
  114. output.close();
  115. }
  116. if(input!=null){
  117. input.close();
  118. }
  119. }catch(IOExceptione){
  120. thrownewRuntimeException(e);
  121. }
  122. if(conn!=null){
  123. conn.disconnect();
  124. }
  125. }
  126. }
  127. publicstaticvoidmain(String[]args){
  128. try{
  129. Stringresponse="";
  130. BufferedReaderin=newBufferedReader(newFileReader("config/actionUrl.properties"));
  131. StringactionUrl=in.readLine();
  132. //讀取表單對應的欄位名稱及其值
  133. PropertiesformDataParams=newProperties();
  134. formDataParams.load(newFileInputStream(newFile("config/formDataParams.properties")));
  135. Set<Map.Entry<Object,Object>>params=formDataParams.entrySet();
  136. //讀取圖片所對應的表單欄位名稱及圖片路徑
  137. PropertiesimageParams=newProperties();
  138. imageParams.load(newFileInputStream(newFile("config/imageParams.properties")));
  139. Set<Map.Entry<Object,Object>>images=imageParams.entrySet();
  140. Image[]files=newImage[images.size()];
  141. inti=0;
  142. for(Map.Entry<Object,Object>image:images){
  143. Imagefile=newImage(image.getValue().toString(),image.getKey().toString());
  144. files[i++]=file;
  145. }
  146. //Imagefile=newImage("images/apple.jpg","upload_file");
  147. //Image[]files=newImage[0];
  148. //files[0]=file;
  149. response=newUploadImage().post(actionUrl,params,files);
  150. System.out.println("返回結果:"+response);
  151. }catch(IOExceptione){
  152. e.printStackTrace();
  153. }
  154. }
  155. }