转自:http://www.linuxidc.com/Linux/2011-08/41944.htm
问题:
Android应用中,当遇到填写用户信息、发表评论等操作,不可避免会遇到“form表单操作”(类似web form操作)上传图片的功能。
在这种情况下,使用Android的HTTPConnection/ ApacheHTTP 通过POST 和GET的方式就实现不了。
解决方法:
Android客户端通过模拟 HTTP multipart/form-data 请求协议信息实现图片上传。
- /**
- *文件名称:UploadImage.java
- *
- *版权信息:ApacheLicense,Version2.0
- *
- *功能描述:实现图片文件上传。
- *
- *创建日期:2011-5-10
- *
- *作者:BertLee
- */
- /*
- *修改历史:
- */
- publicclassUploadImage{
- Stringmultipart_form_data="multipart/form-data";
- StringtwoHyphens="--";
- Stringboundary="****************fD4fH3gL0hK7aI6";//数据分隔符
- StringlineEnd=System.getProperty("line.separator");//Thevalueis"\r\n"inWindows.
- /*
- *上传图片内容,格式请参考HTTP协议格式。
- *人人网Photos.upload中的”程序调用“http://wiki.dev.renren.com/wiki/Photos.upload#.E7.A8.8B.E5.BA.8F.E8.B0.83.E7.94.A8
- *对其格式解释的非常清晰。
- *格式如下所示:
- *--****************fD4fH3hK7aI6
- *Content-Disposition:form-data;name="upload_file";filename="apple.jpg"
- *Content-Type:image/jpeg
- *
- *这儿是文件的内容,二进制流的形式
- */
- privatevoidaddImageContent(Image[]files,DataOutputStreamoutput){
- for(Imagefile:files){
- StringBuildersplit=newStringBuilder();
- split.append(twoHyphens+boundary+lineEnd);
- split.append("Content-Disposition:form-data;name=\""+file.getFormName()+"\";filename=\""+file.getFileName()+"\""+lineEnd);
- split.append("Content-Type:"+file.getContentType()+lineEnd);
- split.append(lineEnd);
- try{
- //发送图片数据
- output.writeBytes(split.toString());
- output.write(file.getData(),0,file.getData().length);
- output.writeBytes(lineEnd);
- }catch(IOExceptione){
- thrownewRuntimeException(e);
- }
- }
- }
- /*
- *构建表单字段内容,格式请参考HTTP协议格式(用FireBug可以抓取到相关数据)。(以便上传表单相对应的参数值)
- *格式如下所示:
- *--****************fD4fH3hK7aI6
- *Content-Disposition:form-data;name="action"
- *//一空行,必须有
- *upload
- */
- privatevoidaddFormField(Set<Map.Entry<Object,Object>>params,DataOutputStreamoutput){
- StringBuildersb=newStringBuilder();
- for(Map.Entry<Object,Object>param:params){
- sb.append(twoHyphens+boundary+lineEnd);
- sb.append("Content-Disposition:form-data;name=\""+param.getKey()+"\""+lineEnd);
- sb.append(lineEnd);
- sb.append(param.getValue()+lineEnd);
- }
- try{
- output.writeBytes(sb.toString());//发送表单字段数据
- }catch(IOExceptione){
- thrownewRuntimeException(e);
- }
- }
- /**
- *直接通过HTTP协议提交数据到服务器,实现表单提交功能。
- *@paramactionUrl上传路径
- *@paramparams请求参数key为参数名,value为参数值
- *@paramfiles上传文件信息
- *@return返回请求结果
- */
- publicStringpost(StringactionUrl,Set<Map.Entry<Object,Object>>params,Image[]files){
- HttpURLConnectionconn=null;
- DataOutputStreamoutput=null;
- BufferedReaderinput=null;
- try{
- URLurl=newURL(actionUrl);
- conn=(HttpURLConnection)url.openConnection();
- conn.setConnectTimeout(120000);
- conn.setDoInput(true);//允许输入
- conn.setDoOutput(true);//允许输出
- conn.setUseCaches(false);//不使用Cache
- conn.setRequestMethod("POST");
- conn.setRequestProperty("Connection","keep-alive");
- conn.setRequestProperty("Content-Type",multipart_form_data+";boundary="+boundary);
- conn.connect();
- output=newDataOutputStream(conn.getOutputStream());
- addImageContent(files,output);//添加图片内容
- addFormField(params,output);//添加表单字段内容
- output.writeBytes(twoHyphens+boundary+twoHyphens+lineEnd);//数据结束标志
- output.flush();
- intcode=conn.getResponseCode();
- if(code!=200){
- thrownewRuntimeException("请求‘"+actionUrl+"’失败!");
- }
- input=newBufferedReader(newInputStreamReader(conn.getInputStream()));
- StringBuilderresponse=newStringBuilder();
- StringoneLine;
- while((oneLine=input.readLine())!=null){
- response.append(oneLine+lineEnd);
- }
- returnresponse.toString();
- }catch(IOExceptione){
- thrownewRuntimeException(e);
- }finally{
- //统一释放资源
- try{
- if(output!=null){
- output.close();
- }
- if(input!=null){
- input.close();
- }
- }catch(IOExceptione){
- thrownewRuntimeException(e);
- }
- if(conn!=null){
- conn.disconnect();
- }
- }
- }
- publicstaticvoidmain(String[]args){
- try{
- Stringresponse="";
- BufferedReaderin=newBufferedReader(newFileReader("config/actionUrl.properties"));
- StringactionUrl=in.readLine();
- //读取表单对应的字段名称及其值
- PropertiesformDataParams=newProperties();
- formDataParams.load(newFileInputStream(newFile("config/formDataParams.properties")));
- Set<Map.Entry<Object,Object>>params=formDataParams.entrySet();
- //读取图片所对应的表单字段名称及图片路径
- PropertiesimageParams=newProperties();
- imageParams.load(newFileInputStream(newFile("config/imageParams.properties")));
- Set<Map.Entry<Object,Object>>images=imageParams.entrySet();
- Image[]files=newImage[images.size()];
- inti=0;
- for(Map.Entry<Object,Object>image:images){
- Imagefile=newImage(image.getValue().toString(),image.getKey().toString());
- files[i++]=file;
- }
- //Imagefile=newImage("images/apple.jpg","upload_file");
- //Image[]files=newImage[0];
- //files[0]=file;
- response=newUploadImage().post(actionUrl,params,files);
- System.out.println("返回结果:"+response);
- }catch(IOExceptione){
- e.printStackTrace();
- }
- }
- }