Android:Volley实现参数,字符数组,文件,图片的上传

来源:互联网 发布:用vb获取网页源代码 编辑:程序博客网 时间:2024/05/29 03:59

1.代码使用

RequestQueue queue = Volley.newRequestQueue(context);MultipartRequest multipartRequest = new MultipartRequest(url, new Response.Listener<String>() {    @Override    public void onResponse(String string) {        //string为服务器返回的字符串        Toast.makeText(context, "更新成功", Toast.LENGTH_SHORT).show();    }}, new Response.ErrorListener() {    @Override    public void onErrorResponse(VolleyError error) {        Toast.makeText(context,"失败",Toast.LENGTH_SHORT).show();    }});// 添加headermultipartRequest.addHeader("header-name", "value");// 通过MultipartEntity来设置参数MultipartEntity multi = multipartRequest.getMultiPartEntity();//传参数multi.addStringPart("userId", userId());//传二进制byte[]multi.addBinaryPart("logo", bytes);//传文件(以图片为例)multi.addFilePart("logo", BitmapToUtils.saveFile(head),"image/png");queue.add(multipartRequest);

2.自定义Request类

package com.gonghoo.Multipart;import android.util.Log;import com.android.volley.AuthFailureError;import com.android.volley.NetworkResponse;import com.android.volley.Request;import com.android.volley.Response;import com.android.volley.toolbox.HttpHeaderParser;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.UnsupportedEncodingException;import java.util.HashMap;import java.util.Map;/** * 上传参数,二进制,文件自定义Request类 * yaoyuan */public class MultipartRequest extends Request<String> {    MultipartEntity mMultiPartEntity = new MultipartEntity();    Map<String, String> mHeaders = new HashMap<String, String>();    private final Response.Listener<String> mListener;    /**     * Creates a new request with the given url.     *     * @param url URL to fetch the string at     * @param listener Listener to receive the String response     */    public MultipartRequest(String url, Response.Listener<String> listener) {        this(url, listener, null);    }    /**     * Creates a new POST request.     *     * @param url URL to fetch the string at     * @param listener Listener to receive the String response     * @param errorListener Error listener, or null to ignore errors     */    public MultipartRequest(String url, Response.Listener<String> listener, Response.ErrorListener errorListener) {        super(Method.POST, url, errorListener);        mListener = listener;    }    /**     * @return     */    public MultipartEntity getMultiPartEntity() {        return mMultiPartEntity;    }    @Override    public String getBodyContentType() {        return mMultiPartEntity.getContentType().getValue();    }    public void addHeader(String key, String value) {        mHeaders.put(key, value);    }    @Override    public Map<String, String> getHeaders() throws AuthFailureError {        return mHeaders;    }    @Override    public byte[] getBody() {        ByteArrayOutputStream bos = new ByteArrayOutputStream();        try {            // multipart body            mMultiPartEntity.writeTo(bos);        } catch (IOException e) {            Log.e("", "IOException writing to ByteArrayOutputStream");        }        return bos.toByteArray();    }    @Override    protected Response<String> parseNetworkResponse(NetworkResponse response) {        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));    }    @Override    protected void deliverResponse(String response) {        if (mListener != null) {            mListener.onResponse(response);        }    }}

3.自定义HttpEntity类(关键类,可以自己定制,我的是以图片png为例)

package com.gonghoo.Multipart;import android.text.TextUtils;import org.apache.http.Header;import org.apache.http.HttpEntity;import org.apache.http.message.BasicHeader;import java.io.*;import java.util.Random;/** * 上传参数,二进制,文件自定义HttpEntity类 * yaoyuan */public class MultipartEntity implements HttpEntity {//参数,二进制,文件上传自定义HttpEntity类 yaoyuan    private final static char[] MULTIPART_CHARS = "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"            .toCharArray();    /**     * 换行符     */    private final String NEW_LINE_STR = "\r\n";    private final String CONTENT_TYPE = "Content-Type: ";    private final String CONTENT_DISPOSITION = "Content-Disposition: ";    /**     * 文本参数和字符集     */    private final String TYPE_TEXT_CHARSET = "text/plain; charset=UTF-8";    /**     * 字节流参数     */    private final String TYPE_OCTET_STREAM = "application/octet-stream";    /**     * 二进制参数     */    private final byte[] BINARY_ENCODING = "Content-Transfer-Encoding: binary\r\n\r\n".getBytes();    /**     * 文本参数     */    private final byte[] BIT_ENCODING = "Content-Transfer-Encoding: 8bit\r\n\r\n".getBytes();    /**     * 分隔符     */    private String mBoundary = null;    /**     * 输出流     */    ByteArrayOutputStream mOutputStream = new ByteArrayOutputStream();    public MultipartEntity() {        this.mBoundary = generateBoundary();    }    /**     * 生成分隔符     *     * @return     */    private final String generateBoundary() {        final StringBuffer buf = new StringBuffer();        final Random rand = new Random();        for (int i = 0; i < 30; i++) {            buf.append(MULTIPART_CHARS[rand.nextInt(MULTIPART_CHARS.length)]);        }        return buf.toString();    }    /**     * 参数开头的分隔符     *     * @throws IOException     */    private void writeFirstBoundary() throws IOException {        mOutputStream.write(("--" + mBoundary + "\r\n").getBytes());    }    /**     * 添加文本参数     *     * @param value     */    public void addStringPart(final String paramName, final String value) {        writeToOutputStream(paramName, value.getBytes(), TYPE_TEXT_CHARSET, BIT_ENCODING, "");    }    /**     * 将数据写入到输出流中     *     * @param rawData     * @param type     * @param encodingBytes     * @param fileName     */    private void writeToOutputStream(String paramName, byte[] rawData, String type,                                     byte[] encodingBytes,                                     String fileName) {        try {            writeFirstBoundary();            mOutputStream.write((CONTENT_TYPE + type + NEW_LINE_STR).getBytes());            mOutputStream                    .write(getContentDispositionBytes(paramName, fileName));            mOutputStream.write(encodingBytes);            mOutputStream.write(rawData);            mOutputStream.write(NEW_LINE_STR.getBytes());        } catch (final IOException e) {            e.printStackTrace();        }    }    /**     * 添加二进制参数, 例如Bitmap的字节流参数     *     * @param rawData     */    public void addBinaryPart(String paramName, final byte[] rawData,final String filetype) {        writeToOutputStream(paramName, rawData, filetype, BINARY_ENCODING, "no-file");    }    /**     * 添加文件参数,可以实现文件上传功能     *     * @param key     * @param file     */    public void addFilePart(final String key, final File file ,final String filetype) {        InputStream fin = null;        try {            fin = new FileInputStream(file);            writeFirstBoundary();            final String type = CONTENT_TYPE + filetype + NEW_LINE_STR;            mOutputStream.write(getContentDispositionBytes(key, file.getName()));            mOutputStream.write(type.getBytes());            mOutputStream.write(BINARY_ENCODING);            final byte[] tmp = new byte[4096];            int len = 0;            while ((len = fin.read(tmp)) != -1) {                mOutputStream.write(tmp, 0, len);            }            mOutputStream.write(NEW_LINE_STR.getBytes());            mOutputStream.flush();        } catch (final IOException e) {            e.printStackTrace();        } finally {            closeSilently(fin);        }    }    private void closeSilently(Closeable closeable) {        try {            if (closeable != null) {                closeable.close();            }        } catch (final IOException e) {            e.printStackTrace();        }    }    private byte[] getContentDispositionBytes(String paramName, String fileName) {        StringBuilder stringBuilder = new StringBuilder();        stringBuilder.append(CONTENT_DISPOSITION + "form-data; name=\"" + paramName + "\"");        // 文本参数没有filename参数,设置为空即可        if (!TextUtils.isEmpty(fileName)) {            stringBuilder.append("; filename=\""                    + fileName + "\"");        }        return stringBuilder.append(NEW_LINE_STR).toString().getBytes();    }    @Override    public long getContentLength() {        return mOutputStream.toByteArray().length;    }    @Override    public Header getContentType() {        return new BasicHeader("Content-Type", "multipart/form-data; boundary=" + mBoundary);    }    @Override    public boolean isChunked() {        return false;    }    @Override    public boolean isRepeatable() {        return false;    }    @Override    public boolean isStreaming() {        return false;    }    @Override    public void writeTo(final OutputStream outstream) throws IOException {        // 参数最末尾的结束符        final String endString = "--" + mBoundary + "--\r\n";        // 写入结束符        mOutputStream.write(endString.getBytes());        //        outstream.write(mOutputStream.toByteArray());    }    @Override    public Header getContentEncoding() {        return null;    }    @Override    public void consumeContent() throws IOException,            UnsupportedOperationException {        if (isStreaming()) {            throw new UnsupportedOperationException(                    "Streaming entity does not implement #consumeContent()");        }    }    @Override    public InputStream getContent() {        return new ByteArrayInputStream(mOutputStream.toByteArray());    }}

4.可以debug看报文的格式,要严格按照要求来,该转行就转行

2 0
原创粉丝点击