Android使用Volley上传文件

一个项目中用到的使用Volley上传头像文件的例子

/**
 * Created by wangshihui on 2015/11/30.
 * 上传文件
 *  url:.....
    method:post
    参数:file
    接口给的参数:file 就是表单的key,传给mFilePartName;
    这是个测试类,测试上传头像没有问题,适合只上传单个文件的场景
 */
public class MultipartRequest extends Request<JSONObject> {
    private String mHeader;
    private Map<String, String> mMap;
    private String cookieFromResp = "";
    private Map<String, String> headerMap = new HashMap<>();
    private MultipartEntity entity = new MultipartEntity();
    private final Response.Listener<JSONObject> mListener;
    private final File mFilePart;
    private String mFilePartName;

    /**
     * @param url
     * @param listener
     * @param errorListener
     * @param file_name
     * @param file
     */
    public MultipartRequest(String url, Response.Listener<JSONObject> listener, Response.ErrorListener errorListener, String file_name,File file)
    {
        super(Method.POST, url, errorListener);
        mListener = listener;
        mFilePart = file;
        mFilePartName=file_name;
        buildMultipartEntity();
    }

    /**
     * 添加文件参数
     */
    private void buildMultipartEntity()
    {
        entity.addPart(mFilePartName, new FileBody(mFilePart));
    }

    @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();
    }

    /**
     * @param response
     * @return
     */
    @Override
    protected Response<JSONObject> parseNetworkResponse(NetworkResponse response)
    {
        try {
        JSONObject jsonObject;
        System.out.println(response.headers.toString());
        if (response.data.length != 0) {
            String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
            jsonObject = new JSONObject(jsonString);
        } else {
            jsonObject = new JSONObject();
        }
        //获取数据头
        mHeader = response.headers.toString();
        //提取Cookie(JSESSIONID)
        Pattern pattern = Pattern.compile("Set-Cookie=.*?;");
        Matcher matcher = pattern.matcher(mHeader);
        if (matcher.find()) {
            cookieFromResp = matcher.group();
            cookieFromResp = cookieFromResp.substring(11, cookieFromResp.length() - 1);
            System.out.println("Cookie: " + cookieFromResp);
        }
        jsonObject.put("Cookie", cookieFromResp);
        return Response.success(jsonObject,
                HttpHeaderParser.parseCacheHeaders(response));
    } catch (UnsupportedEncodingException e) {
        return Response.error(new ParseError(e));
    } catch (JSONException je) {
        return Response.error(new ParseError(je));
    }
    }

    /**
     * @param response
     */
    @Override
    protected void deliverResponse(JSONObject response)
    {
        mListener.onResponse(response);
    }

    @Override
    protected Map<String, String> getParams() throws AuthFailureError {
        return mMap;
    }

    /**
     * @return
     * @throws AuthFailureError
     */
    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        return headerMap;
    }

    /**
     * @return
     */
    @Override
    public RetryPolicy getRetryPolicy() {
        RetryPolicy retryPolicy = new DefaultRetryPolicy(5000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
        return retryPolicy;
    }

    /**
     * @param cookie
     */
    //将Cookie加入数据头
    public void setSendCookie(String cookie) {
        headerMap.put("Cookie", cookie);
    }
}

调用方法如下:

//指定url路径
String url = "http://182.92.....";
MultipartRequest multipartRequest = new MultipartRequest(
        url, new Response.Listener<JSONObject>() {
    @Override
    public void onResponse(JSONObject response) {
        saveSessionID(response);       
    }
}, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError e) {
        Log.e(TAG, e.getMessage(), e);
        try {
            byte[] htmlBodyBytes = e.networkResponse.data;
            Log.e(TAG, new String(htmlBodyBytes), e);
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        ToastUtil.showShortToast(UserCenterActivity.this, "网络连接异常");
    }
}, "file", mSelectedPictureFile);
multipartRequest.setSendCookie(loadSessionID());
multipartRequest.setTag(TAG);
client.addTask(multipartRequest);
private File mSelectedPictureFile;

mSelectedPictureFile是一个File文件,参数名是file

通信成功保存Cookie

saveSessionID(response);  

发送请求上传cookie

multipartRequest.setSendCookie(loadSessionID());

client是一个Volley的简单封装

protected AsynHttpClient client;

public class AsynHttpClient {

    //volley的请求队列
    private RequestQueue requestQueue;
    //保证全局变量是单一的
    private static AsynHttpClient instance;

    private Context mContext;

    private AsynHttpClient(Context context) {
        requestQueue = Volley.newRequestQueue(context);
        this.mContext = context;
    }
    /**
     * 单列模式,让AsynHttpClient在整个项目中保持只有一个
     * @param context
     * @return
     */
    public static AsynHttpClient getInstance(Context context) {
        if (instance==null){
            synchronized (AsynHttpClient.class){
                if (instance==null){
                    instance=new AsynHttpClient(context);
                }
            }
        }
        return instance;
    }

    /**
     * 添加任务到volley的请求队列中去,并不会立即执行
     * @param task
     */
    public  void addTask(Request task){
        requestQueue.add(task);
    }

    public RequestQueue getRequestQueue() {
        return requestQueue;
    }
}

你可能感兴趣的:(Android开发)