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>params,DataOutputStreamoutput){
  57. StringBuildersb=newStringBuilder();
  58. for(Map.Entryparam: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>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>params=formDataParams.entrySet();
  136. //读取图片所对应的表单字段名称及图片路径
  137. PropertiesimageParams=newProperties();
  138. imageParams.load(newFileInputStream(newFile("config/imageParams.properties")));
  139. Set>images=imageParams.entrySet();
  140. Image[]files=newImage[images.size()];
  141. inti=0;
  142. for(Map.Entryimage: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. }

你可能感兴趣的:(Android模拟 HTTP multipart/form-data 请求协议信息实现图片上传)