使用Volley上傳檔案,volley上傳檔案

來源:互聯網
上載者:User

使用Volley上傳檔案,volley上傳檔案

使用瀏覽器上傳檔案,然後通過Wireshark抓包分析,發現發送的資料大概是這個樣子。

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

 首先來自訂一個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 {    }}

現在來解釋一下,首先這是支援多檔案上傳的,資料格式一共包括四部分,Content-Type,First boundary,檔案位元據[],及Last boundary。可以有多個檔案,使用addFile方法插入,檔案之間需要有分隔字元Boundary。每個檔案需要有Content-Disposition及Content-Type

 

然後再自訂一個Request,根據需要使用不同的構造方法

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

代碼是放在Volley中其他類型Request來寫的,沒什麼好說的。

最後就是如何調用

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

執行個體化一個新的Request對象,傳入Method,Url,然後通過Request對象來擷取Entity,通過addFile()方法來傳入需要上傳的檔案,最後加入requestQueue,使用方法與其他類型Request相同。

 

備忘:

需要添加以下依賴:

    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')

  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.