Use Volley to upload files and volley to upload files

Source: Internet
Author: User

Use Volley to upload files and volley to upload files

Upload files in a browser, and then analyze the packets through Wireshark. It is found that the data sent is like this.

MIME Multipart Media Encapsulation, Type: multipart/form-data, Boundary: "----WebKitFormBoundary1UBMMKIkN58civN4"    [Type: multipart/form-data]    First boundary: ------WebKitFormBoundary1UBMMKIkN58civN4\r\n    Encapsulated multipart part:         Content-Disposition: form-data; name="name"\r\n\r\n        Data (16 bytes)    Boundary: \r\n------WebKitFormBoundary1UBMMKIkN58civN4\r\n    Encapsulated multipart part:  (image/png)        Content-Disposition: form-data; name="photo[]"; filename="Screenshot (2).png"\r\n        Content-Type: image/png\r\n\r\n        Portable Network Graphics    Boundary: \r\n------WebKitFormBoundary1UBMMKIkN58civN4\r\n    Encapsulated multipart part:  (image/png)    Boundary: \r\n------WebKitFormBoundary1UBMMKIkN58civN4\r\n    Encapsulated multipart part:  (image/png)    Boundary: \r\n------WebKitFormBoundary1UBMMKIkN58civN4\r\n    Encapsulated multipart part:  (image/png)    Boundary: \r\n------WebKitFormBoundary1UBMMKIkN58civN4\r\n    Encapsulated multipart part:  (image/png)    Last boundary: \r\n------WebKitFormBoundary1UBMMKIkN58civN4--\r\n

First, define an HttpEntity,

package cc.dewdrop.volleydemo.utils;import com.android.volley.VolleyLog;import org.apache.http.Header;import org.apache.http.HttpEntity;import org.apache.http.message.BasicHeader;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.Closeable;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import javax.activation.MimetypesFileTypeMap;/** * Created by Tingkuo on 12/1/2015. */public class FileUploadEntity implements HttpEntity {    private static final String TAG = FileUploadEntity.class.getSimpleName();    private static final String BOUNDARY = "__FILE_UPLOAD_ENTITY__";    private ByteArrayOutputStream mOutputStream;    public FileUploadEntity() {        mOutputStream = new ByteArrayOutputStream();        try {            writeFirstBoundary();        } catch (IOException e) {            e.printStackTrace();        }    }    private void writeFirstBoundary() throws IOException {        VolleyLog.e("writeFirstBoundary");        mOutputStream.write(("--" + BOUNDARY + "\r\n").getBytes());        mOutputStream.write(("Content-Disposition: form-data; name=\"" + "name" + "\"\r\n\r\n").getBytes());        mOutputStream.write("Content-Transfer-Encoding: binary\n\n".getBytes());        mOutputStream.flush();    }    private void writeLastBoundary() throws IOException {        VolleyLog.e("writeLastBoundary");        mOutputStream.write(("\r\n--" + BOUNDARY + "--\r\n").getBytes());    }    public void addFile(final String key, final File file) {        VolleyLog.e("addFile");        InputStream inputStream = null;        try {            mOutputStream.write(("\r\n--" + BOUNDARY + "\r\n").getBytes());            StringBuilder stringBuilderContentDisposition = new StringBuilder();            stringBuilderContentDisposition.append("Content-Disposition: ");            stringBuilderContentDisposition.append("form-data; ");            stringBuilderContentDisposition.append("name=\"" + key + "\"; ");            stringBuilderContentDisposition.append("filename=\"" + file.getName() + "\"\r\n");            mOutputStream.write(stringBuilderContentDisposition.toString().getBytes());            StringBuilder stringBuilderContentType = new StringBuilder();            stringBuilderContentType.append("Content-Type: ");            stringBuilderContentType.append(new MimetypesFileTypeMap().getContentType(file).toString());            stringBuilderContentType.append("\r\n\r\n");            mOutputStream.write(stringBuilderContentType.toString().getBytes());            inputStream = new FileInputStream(file);            final byte[] buffer = new byte[1024];            int len = 0;            while ((len = inputStream.read(buffer)) != -1) {                VolleyLog.e("len --> %s", String.valueOf(len));                mOutputStream.write(buffer, 0, len);            }            VolleyLog.e("===last====len --> %s", String.valueOf(len));            mOutputStream.flush();        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        } finally {            closeSilently(inputStream);        }    }    private void closeSilently(Closeable closeable) {        try {            if (closeable != null) {                closeable.close();            }        } catch (final IOException e) {            e.printStackTrace();        }    }    @Override    public boolean isRepeatable() {        return false;    }    @Override    public boolean isChunked() {        return false;    }    @Override    public long getContentLength() {        return mOutputStream.toByteArray().length;    }    @Override    public Header getContentType() {        return new BasicHeader("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);    }    @Override    public Header getContentEncoding() {        return null;    }    @Override    public InputStream getContent() throws IOException, UnsupportedOperationException {        return new ByteArrayInputStream(mOutputStream.toByteArray());    }    @Override    public void writeTo(OutputStream outputStream) throws IOException {        writeLastBoundary();        outputStream.write(mOutputStream.toByteArray());    }    @Override    public boolean isStreaming() {        return false;    }    @Override    public void consumeContent() throws IOException {    }}

Here, we will explain that Multifile upload is supported. The data format consists of four parts: Content-Type, First boundary, binary data [], and Last boundary. You can insert multiple files using addFile. The Boundary delimiter must be used between files. Each file requires Content-Disposition and Content-Type.

 

Then, customize a Request and use different constructor methods as needed.

package cc.dewdrop.volleydemo.utils;import com.android.volley.AuthFailureError;import com.android.volley.NetworkResponse;import com.android.volley.Request;import com.android.volley.Response;import com.android.volley.Response.Listener;import com.android.volley.Response.ErrorListener;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;/** * Created by Tingkuo on 12/2/2015. */public class FileUploadRequest extends Request<String> {    private final Listener<String> mListener;    private FileUploadEntity mFileUploadEntity = new FileUploadEntity();    private Map<String, String> mHeaders = new HashMap<>();    public FileUploadRequest(String url, Listener<String> listener) {        this(url, listener, null);    }    public FileUploadRequest(String url, Listener<String> listener, ErrorListener errorListener) {        this(Method.POST, url, listener, errorListener);    }    public FileUploadRequest(int method, String url, Listener<String> listener, ErrorListener errorListener) {        super(method, url, errorListener);        this.mListener = listener;    }    public FileUploadEntity getFileUploadEntity() {        return mFileUploadEntity;    }    @Override    public String getBodyContentType() {        return mFileUploadEntity.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() throws AuthFailureError {        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();        try {            mFileUploadEntity.writeTo(outputStream);        } catch (IOException e) {            e.printStackTrace();        }        return outputStream.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);        }    }}

The code is written in other types of requests in Volley.

Finally, how to call

    private void simpleUploadFile() {        File file = new File(Environment.getExternalStorageDirectory().getPath() + "/upload.png");        fileUploadRequest = new FileUploadRequest(                Request.Method.POST,                urlList.get(2),                new Response.Listener<String>() {                    @Override                    public void onResponse(String response) {                        textViewInfo.setText("Post Succeed:\n" + response.replace("<br>", "\n"));                        Log.e(TAG, response);                        dialog.dismiss();                    }                },                new Response.ErrorListener() {                    @Override                    public void onErrorResponse(VolleyError error) {                        textViewInfo.setText("Post Failed:\n" + error.getMessage());                        Log.e(TAG, error.getMessage());                        dialog.dismiss();                    }                }        );        fileUploadRequest.addHeader("User-Agent", "Android 5.1.1");        FileUploadEntity fileUploadEntity = fileUploadRequest.getFileUploadEntity();        fileUploadEntity.addFile("file[]", file);        fileUploadEntity.addFile("file[]", file);        fileUploadEntity.addFile("file[]", file);        fileUploadEntity.addFile("file[]", file);        fileUploadEntity.addFile("file[]", file);        requestQueue.add(fileUploadRequest);        dialog.show();    }

Instantiate a new Request object, pass in Method and Url, get Entity through the Request object, pass in the file to be uploaded through addFile () Method, and add requestQueue, the usage is the same as that of other types of requests.

 

Note:

You need to add the following dependencies:

    compile 'org.apache.httpcomponents:httpcore:4.4.4'    compile 'org.apache.httpcomponents:httpmime:4.5.1'    compile files('libs/volley.jar')    compile files('libs/activation.jar')

  

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.