Android volley(5)MultipartEntity 封装 volley上传 —— 一个参数多张图、多张图片多张图

博客源址:http://blog.csdn.net/kroclin/article/details/40631271

一、前言

Google自从2013的IO大会上发布volley框架之后就受到广泛应用,的确,用过几个网络请求库,感觉volley还是很好用的,用起来也特别方便顺手。但是遇到上传文件就比较麻烦,尤其是有时候想一个参数名对应多个文件,就像我坑爹后台给我的接口,就是参数的key叫做images,然后value是多图。。多图。。。图。。。。

有许多网络请求库的post请求时,带参数使用hashmap进行封装的,但是hashmap是以键值对形式存值的,这里有一个问题就是一个key对应一个value,当你连续put进去两个key是一样的时候,后者就会将前者取代掉。最后只剩下一个参数而已。这样是达不到需求的。而有一个解决办法就是开多个子线程,每次传一张图片过去,其实这样也行,具体还是看需求,我这里要讨论的是一次性传多图。


二、解决

而如果使用volley的话,因为请求数据那些都很简便,但遇到上传文件就麻烦那可不好,同时使用多个网络请求类库也是不太建议的。所以这里就给出了一种解决方法,也要借助一个jar包,这里用到的是httpmime(点击下载),主要用到的是MultipartEntity类,可以对请求参数进行封装。


主要是继承volley的Request类,然后通过使用httpmim的MultipartEntity类对文件参数进行封装,这里实现了一个参数名对应一个文件,

一个参数名对应多个文件,如果还要多个参数名对应多个文件可以自己试着实现一下哈


[java]  view plain  copy
  1. package com.android.volley.toolbox;  
  2.   
  3. import java.io.ByteArrayOutputStream;  
  4. import java.io.File;  
  5. import java.io.IOException;  
  6. import java.io.UnsupportedEncodingException;  
  7. import java.nio.charset.Charset;  
  8. import java.util.ArrayList;  
  9. import java.util.Collections;  
  10. import java.util.HashMap;  
  11. import java.util.List;  
  12. import java.util.Map;  
  13.   
  14. import org.apache.http.entity.mime.MultipartEntity;  
  15. import org.apache.http.entity.mime.content.FileBody;  
  16. import org.apache.http.entity.mime.content.StringBody;  
  17.   
  18. import com.android.volley.AuthFailureError;  
  19. import com.android.volley.NetworkResponse;  
  20. import com.android.volley.Request;  
  21. import com.android.volley.Response;  
  22. import com.android.volley.VolleyLog;  
  23. import com.common.utils.CLog;  
  24. import com.common.utils.FileUtil;  
  25.   
  26. public class MultipartRequest extends Request<String> {  
  27.   
  28.     private MultipartEntity entity = new MultipartEntity();  
  29.   
  30.     private final Response.Listener<String> mListener;  
  31.   
  32.     private List<File> mFileParts;  
  33.     private String mFilePartName;  
  34.     private Map<String, String> mParams;  
  35.     /** 
  36.      * 单个文件 
  37.      * @param url 
  38.      * @param errorListener 
  39.      * @param listener 
  40.      * @param filePartName 
  41.      * @param file 
  42.      * @param params 
  43.      */  
  44.     public MultipartRequest(String url, Response.ErrorListener errorListener,  
  45.             Response.Listener<String> listener, String filePartName, File file,  
  46.             Map<String, String> params) {  
  47.         super(Method.POST, url, errorListener);  
  48.   
  49.         mFileParts = new ArrayList<File>();  
  50.         if (file != null) {  
  51.             mFileParts.add(file);  
  52.         }  
  53.         mFilePartName = filePartName;  
  54.         mListener = listener;  
  55.         mParams = params;  
  56.         buildMultipartEntity();  
  57.     }  
  58.     /** 
  59.      * 多个文件,对应一个key 
  60.      * @param url 
  61.      * @param errorListener 
  62.      * @param listener 
  63.      * @param filePartName 
  64.      * @param files 
  65.      * @param params 
  66.      */  
  67.     public MultipartRequest(String url, Response.ErrorListener errorListener,  
  68.             Response.Listener<String> listener, String filePartName,  
  69.             List<File> files, Map<String, String> params) {  
  70.         super(Method.POST, url, errorListener);  
  71.         mFilePartName = filePartName;  
  72.         mListener = listener;  
  73.         mFileParts = files;  
  74.         mParams = params;  
  75.         buildMultipartEntity();  
  76.     }  
  77.   
  78.     private void buildMultipartEntity() {  
  79.         if (mFileParts != null && mFileParts.size() > 0) {  
  80.             for (File file : mFileParts) {  
  81.                 entity.addPart(mFilePartName, new FileBody(file));  
  82.             }  
  83.             long l = entity.getContentLength();  
  84.             CLog.log(mFileParts.size()+"个,长度:"+l);  
  85.         }  
  86.   
  87.         try {  
  88.             if (mParams != null && mParams.size() > 0) {  
  89.                 for (Map.Entry<String, String> entry : mParams.entrySet()) {  
  90.                     entity.addPart(  
  91.                             entry.getKey(),  
  92.                             new StringBody(entry.getValue(), Charset  
  93.                                     .forName("UTF-8")));  
  94.                 }  
  95.             }  
  96.         } catch (UnsupportedEncodingException e) {  
  97.             VolleyLog.e("UnsupportedEncodingException");  
  98.         }  
  99.     }  
  100.   
  101.     @Override  
  102.     public String getBodyContentType() {  
  103.         return entity.getContentType().getValue();  
  104.     }  
  105.   
  106.     @Override  
  107.     public byte[] getBody() throws AuthFailureError {  
  108.         ByteArrayOutputStream bos = new ByteArrayOutputStream();  
  109.         try {  
  110.             entity.writeTo(bos);  
  111.         } catch (IOException e) {  
  112.             VolleyLog.e("IOException writing to ByteArrayOutputStream");  
  113.         }  
  114.         return bos.toByteArray();  
  115.     }  
  116.   
  117.     @Override  
  118.     protected Response<String> parseNetworkResponse(NetworkResponse response) {  
  119.         CLog.log("parseNetworkResponse");  
  120.         if (VolleyLog.DEBUG) {  
  121.             if (response.headers != null) {  
  122.                 for (Map.Entry<String, String> entry : response.headers  
  123.                         .entrySet()) {  
  124.                     VolleyLog.d(entry.getKey() + "=" + entry.getValue());  
  125.                 }  
  126.             }  
  127.         }  
  128.   
  129.         String parsed;  
  130.         try {  
  131.             parsed = new String(response.data,  
  132.                     HttpHeaderParser.parseCharset(response.headers));  
  133.         } catch (UnsupportedEncodingException e) {  
  134.             parsed = new String(response.data);  
  135.         }  
  136.         return Response.success(parsed,  
  137.                 HttpHeaderParser.parseCacheHeaders(response));  
  138.     }  
  139.   
  140.   
  141.     /* 
  142.      * (non-Javadoc) 
  143.      *  
  144.      * @see com.android.volley.Request#getHeaders() 
  145.      */  
  146.     @Override  
  147.     public Map<String, String> getHeaders() throws AuthFailureError {  
  148.         VolleyLog.d("getHeaders");  
  149.         Map<String, String> headers = super.getHeaders();  
  150.   
  151.         if (headers == null || headers.equals(Collections.emptyMap())) {  
  152.             headers = new HashMap<String, String>();  
  153.         }  
  154.   
  155.   
  156.         return headers;  
  157.     }  
  158.   
  159.     @Override  
  160.     protected void deliverResponse(String response) {  
  161.         mListener.onResponse(response);  
  162.     }  
  163. }  


通过这个请求就可以上传多文件了,也不做多解释,代码也比较简单。我也对这种方法测试过了,但是由于是和服务器进行打交道,这里确实没有什么可以展示出来,不过我还是喜欢有说服力的描述,所谓有图有真相哈哈,上两个图在做解释






这里是从我的log截下来的两张图,图一是我装进5个相同文件之后打印出entity的大小,显示是8347505字节,图二是我装进3个相同文件(跟前

面5个的文件都是一样的)之后打印出的大小,是5005805字节,我相信思维不迟钝的童鞋应该可以看得出这种方法确实可行了吧。因为我已经把

文件装进entity了,而且不同个大小不一样,说明里面装入了多个文件,萌萌哒~~

好啦,就这样啦。早睡早起,做个健康的程序员。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值