使用volley请求数据很简便,但遇到上传文件就麻烦那可不好,同时使用多个网络请求类库也是不太建议的。所以这里就给出了一种解决方法,也要借助一个jar包,这里用到的是httpmime(点击下载),主要用到的是MultipartEntity类,可以对请求参数进行封装。
主要是继承volley的Request类,然后通过使用httpmim的MultipartEntity类对文件参数进行封装,这里实现了一个参数名对应一个文件,
一个参数名对应多个文件,如果还要多个参数名对应多个文件可以自己试着实现一下哈:
package com.android.volley.toolbox; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.http.entity.mime.MultipartEntity; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.entity.mime.content.StringBody; import com.android.volley.AuthFailureError; import com.android.volley.NetworkResponse; import com.android.volley.Request; import com.android.volley.Response; import com.android.volley.VolleyLog; import com.common.utils.CLog; import com.common.utils.FileUtil; public class MultipartRequest extends Request<String> { private MultipartEntity entity = new MultipartEntity(); private final Response.Listener<String> mListener; private List<File> mFileParts; private String mFilePartName; private Map<String, String> mParams; /** * 单个文件 * @param url * @param errorListener * @param listener * @param filePartName * @param file * @param params */ public MultipartRequest(String url, Response.ErrorListener errorListener, Response.Listener<String> listener, String filePartName, File file, Map<String, String> params) { super(Method.POST, url, errorListener); mFileParts = new ArrayList<File>(); if (file != null) { mFileParts.add(file); } mFilePartName = filePartName; mListener = listener; mParams = params; buildMultipartEntity(); } /** * 多个文件,对应一个key * @param url * @param errorListener * @param listener * @param filePartName * @param files * @param params */ public MultipartRequest(String url, Response.ErrorListener errorListener, Response.Listener<String> listener, String filePartName, List<File> files, Map<String, String> params) { super(Method.POST, url, errorListener); mFilePartName = filePartName; mListener = listener; mFileParts = files; mParams = params; buildMultipartEntity(); } private void buildMultipartEntity() { if (mFileParts != null && mFileParts.size() > 0) { for (File file : mFileParts) { entity.addPart(mFilePartName, new FileBody(file)); } long l = entity.getContentLength(); CLog.log(mFileParts.size()+"个,长度:"+l); } try { if (mParams != null && mParams.size() > 0) { for (Map.Entry<String, String> entry : mParams.entrySet()) { entity.addPart( entry.getKey(), new StringBody(entry.getValue(), Charset .forName("UTF-8"))); } } } catch (UnsupportedEncodingException e) { VolleyLog.e("UnsupportedEncodingException"); } } @Override public String getBodyContentType() { return entity.getContentType().getValue(); } @Override public byte[] getBody() throws AuthFailureError { ByteArrayOutputStream bos = new ByteArrayOutputStream(); try { entity.writeTo(bos); } catch (IOException e) { VolleyLog.e("IOException writing to ByteArrayOutputStream"); } return bos.toByteArray(); } @Override protected Response<String> parseNetworkResponse(NetworkResponse response) { CLog.log("parseNetworkResponse"); if (VolleyLog.DEBUG) { if (response.headers != null) { for (Map.Entry<String, String> entry : response.headers .entrySet()) { VolleyLog.d(entry.getKey() + "=" + entry.getValue()); } } } String parsed; try { parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers)); } catch (UnsupportedEncodingException e) { parsed = new String(response.data); } return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response)); } /* * (non-Javadoc) * * @see com.android.volley.Request#getHeaders() */ @Override public Map<String, String> getHeaders() throws AuthFailureError { VolleyLog.d("getHeaders"); Map<String, String> headers = super.getHeaders(); if (headers == null || headers.equals(Collections.emptyMap())) { headers = new HashMap<String, String>(); } return headers; } @Override protected void deliverResponse(String response) { mListener.onResponse(response); } }
通过这个请求就可以上传多文件了,也不做多解释,代码也比较简单。我也对这种方法测试过了,但是由于是和服务器进行打交道,这里确实没有什么可以展示出来,不过我还是喜欢有说服力的描述,所谓有图有真相哈哈,上两个图在做解释
这里是从我的log截下来的两张图,图一是我装进5个相同文件之后打印出entity的大小,显示是8347505字节,图二是我装进3个相同文件(跟前
面5个的文件都是一样的)之后打印出的大小,是5005805字节,我相信思维不迟钝的童鞋应该可以看得出这种方法确实可行了吧。因为我已经把
文件装进entity了,而且不同个大小不一样,说明里面装入了多个文件,萌萌哒~~
好啦,就这样啦。早睡早起,做个健康的程序员。
类似:
Android基于Volley实现多文件/图片上传(包含服务器端)
http://blog.csdn.net/yanzi1225627/article/details/49945915
demo:https://github.com/yanzi1225627/TestMultipartRequest