Android Customizes PostUploadRequest Upload Files Using Volley Framework

  • 2021-10-27 09:15:23
  • OfStack

Find a problem

The project has the function of publishing dynamic, which can upload text and pictures to the server.
Volley realizes the function of uploading files by customizing PostUploadRequest. This paper takes uploading a picture as an example.

Data format

The following is the data format of the image upload instance in the project
Multiple pictures can be uploaded by adding--WebKitFormBoundary content


POST /CloudLife/user/social HTTP/1.1
Host: localhost
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://localhost
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryzayymBT8Owg2UzBR
Referer: http://localhost/CloudLife/upload.jsp
Accept-Encoding: gzip,deflate,sdch
Accept-Language: zh-CN,zh;q=0.8
Cookie: CLOUD_LIFE=03F21B9A9D9B4FF2BF443290A9CD8E2C; USER=18060506304; JSESSIONID=C4AB532929FA43230FA193A98197F962
Content-Length: 12444

------WebKitFormBoundaryzayymBT8Owg2UzBR
Content-Disposition: form-data; name="text"

 Published circle content 
------WebKitFormBoundaryzayymBT8Owg2UzBR
Content-Disposition: form-data; name="file"; filename=" Here is the file name "
Content-Type: image/png
 Empty here 1 Row   The next step is 2 Content of binary picture file 
------WebKitFormBoundaryzayymBT8Owg2UzBR--
 This is blank 1 Row 

There are a total of plus the ending line, there are 5 lines, the binary number of the picture, and the whole count is 1 line; Let's analyze it below:

1. Line 1: "+ boundary +"\ r\ n ";
File upload remains unchanged at the beginning of submitting data;

2. Line 2: Content-Disposition: form-data; name= "parameter name"; filename= "uploaded file name" + "\ r\ n"

3. Line 3: Content-Type: mime type of file + "\ r\ n"
This 1 line is necessary for file uploading, while ordinary text submission is optional, and mime type needs to be queried according to documents;

4. Line 4: "\ r\ n"

5. The binary data of the file in Line 5 + "\ r\ n":
Ending line: "" + boundary + "" + "\ r\ n"
You can upload multiple files at the same time. Repeat steps 1, 2, 3, 4 and 5 when uploading multiple files, and add the end line of unification 1 at the end of the last file.

Uploaded image entity class


import java.io.ByteArrayOutputStream;
import android.graphics.Bitmap;

/*
 *  Uploaded image entity class 
 * */
public class FormImage {

 //  Name of the parameter 
 private String mName;

 //  Filename 
 private String mFileName;

 //  Documentary  mime You need to query according to the document 
 private String mMime;

 //  Need to upload the picture resources, because the test here is for convenience, directly put  bitmap  Pass it in, really in the project 1 I wouldn't do this, 
 //  Instead, pass the path of the picture, and here the picture is carried out 2 Binary conversion 
 private Bitmap mBitmap = null;

 public FormImage(Bitmap bitmap) {
 this.mBitmap = bitmap;
 }

 public String getName() {
 return "file";
 }

 public String getFileName() {
 return "add.png";
 }

 //  Perform on the picture 2 Binary conversion 
 public byte[] getValue() {
 ByteArrayOutputStream bos = new ByteArrayOutputStream();
 mBitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos);
 return bos.toByteArray();
 }

 //  Because I know it's  png  File, so look it up directly according to the document 
 public String getMime() {
 return "image/png";
 }
}

Customized PostUploadRequest


import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;

import org.apache.http.protocol.HTTP;
import org.json.JSONException;
import org.json.JSONObject;

import com.android.volley.AuthFailureError;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.toolbox.HttpHeaderParser;

import android.util.Log;

/*
 *  Send the file's volley 
 * post Request  Cookie
 * */
public class PostUploadRequest extends Request<JSONObject> {

 private Map<String, String> sendHeader = new HashMap<String, String>();

 //  When the correct data is used, it will be used back 
 private Response.Listener<JSONObject> mListener;

 //  Request   Data is passed in as parameters  
 private String content;
 private FormImage mImage;

 //  Data divider 
 private String BOUNDARY = "----CloudLifeUpLoadImage"; 
 private String MULTIPART_FORM_DATA = "multipart/form-data";

 public PostUploadRequest(String url, String text, FormImage Item, Response.Listener<JSONObject> listener,Response.ErrorListener errorListener) {

 super(Method.POST, url, errorListener);
 this.mListener = listener;
 setShouldCache(false);
 mImage = Item;
 content = text;

 //  Set the response event of the request, because it takes a long time to upload the file, so it is increased here and set to 5 Seconds 
 setRetryPolicy(new DefaultRetryPolicy(5000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
  DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
 }

 /*
 *  Here's where you start parsing the data 
 * @param response
 *  Response from the network
 * @return
 * */
 @Override
 protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
 try {
  //  Prevent Chinese garbled codes 
  @SuppressWarnings("deprecation")
  String jsonString = new String(response.data, HTTP.UTF_8);

  JSONObject jsonObject = new JSONObject(jsonString);

  Log.w("upLoad", "jsonObject " + jsonObject.toString());

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

 /*
 *  Callback the correct data 
 * @param response
 *  The parsed response returned by
 * */
 @Override
 protected void deliverResponse(JSONObject response) {
 mListener.onResponse(response);
 }

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

 public void setSendCookie(String cookie) {
 sendHeader.put("Cookie", cookie);
 }

 @Override
 public byte[] getBody() throws AuthFailureError {
 ByteArrayOutputStream bos = new ByteArrayOutputStream();

 StringBuffer sb = new StringBuffer();

 if (content == null) {
  /**
  *  Picture 
  */
  /*  No. 1 1 Row  */
  // `"--" + BOUNDARY + "\r\n"`
  sb.append("--" + BOUNDARY + "\r\n");

  /*  No. 1 2 Row  */
  // Content-Disposition: form-data; name=" Name of the parameter "; filename=" Uploaded file name " +
  // "\r\n"
  sb.append("Content-Disposition: form-data;");
  sb.append(" name=\"");
  sb.append(mImage.getName());
  sb.append("\"");
  sb.append("; filename=\"");
  sb.append(mImage.getFileName());
  sb.append("\"");
  sb.append("\r\n");

  /*  No. 1 3 Row  */
  // Content-Type:  Documentary  mime  Type  + "\r\n"
  sb.append("Content-Type: ");
  sb.append(mImage.getMime());
  sb.append("\r\n");

  /*  No. 1 4 Row  */
  // "\r\n"  Blank 1 Row 
  sb.append("\r\n");

  try {
  bos.write(sb.toString().getBytes("utf-8"));
  /*  No. 1 5 Row  */
  //  Documentary 2 Binary data  + "\r\n"
  bos.write(mImage.getValue());
  bos.write("\r\n".getBytes("utf-8"));
  } catch (IOException e) {
  e.printStackTrace();
  }

  /*  Ending line  */
  // `"--" + BOUNDARY + "--" + "\r\n"`
  String endLine = "--" + BOUNDARY + "--" + "\r\n";
  try {
  bos.write(endLine.toString().getBytes("utf-8"));
  } catch (IOException e) {
  e.printStackTrace();
  }
  Log.v("upLoad", "=====formImage====\n" + bos.toString());
  return bos.toByteArray();
 }
 /**
  *  Text 
  */
 /*  No. 1 1 Row  */
 // `"--" + BOUNDARY + "\r\n"`
 sb.append("--" + BOUNDARY + "\r\n");

 /*  No. 1 2 Row  */
 // Content-Disposition: form-data; name="text" + "\r\n"
 sb.append("Content-Disposition: form-data;");
 sb.append(" name=\"");
 sb.append("text");
 sb.append("\"");
 sb.append("\r\n");

 /*  No. 1 3 Row  */
 // "\r\n"  Blank 1 Row 
 sb.append("\r\n");

 /*  No. 1 4 Row  */
 //  Text content 
 sb.append(content);
 sb.append("\r\n");

 if (mImage == null) {
  /*  Ending line  */
  // `"--" + BOUNDARY + "--" + "\r\n"`
  String endLine = "--" + BOUNDARY + "--" + "\r\n";
  try {
  bos.write(sb.toString().getBytes("utf-8"));
  bos.write(endLine.toString().getBytes("utf-8"));
  } catch (IOException e) {
  e.printStackTrace();
  }
  Log.v("upLoad", "=====formImage====\n" + bos.toString());
  return bos.toByteArray();
 } else {
  /**
  *  Picture 
  */
  /*  No. 1 1 Row  */
  // `"--" + BOUNDARY + "\r\n"`
  sb.append("--" + BOUNDARY + "\r\n");

  /*  No. 1 2 Row  */
  // Content-Disposition: form-data; name=" Name of the parameter "; filename=" Uploaded file name " +
  // "\r\n"
  sb.append("Content-Disposition: form-data;");
  sb.append(" name=\"");
  sb.append(mImage.getName());
  sb.append("\"");
  sb.append("; filename=\"");
  sb.append(mImage.getFileName());
  sb.append("\"");
  sb.append("\r\n");

  /*  No. 1 3 Row  */
  // Content-Type:  Documentary  mime  Type  + "\r\n"
  sb.append("Content-Type: ");
  sb.append(mImage.getMime());
  sb.append("\r\n");

  /*  No. 1 4 Row  */
  // "\r\n"  Blank 1 Row 
  sb.append("\r\n");

  try {
  bos.write(sb.toString().getBytes("utf-8"));
  /*  No. 1 5 Row  */
  //  Documentary 2 Binary data  + "\r\n"
  bos.write(mImage.getValue());
  bos.write("\r\n".getBytes("utf-8"));
  } catch (IOException e) {
  e.printStackTrace();
  }

 }

 /*  Ending line  */
 // `"--" + BOUNDARY + "--" + "\r\n"`
 String endLine = "--" + BOUNDARY + "--" + "\r\n";
 try {
  bos.write(endLine.toString().getBytes("utf-8"));
 } catch (IOException e) {
  e.printStackTrace();
 }
 Log.v("upLoad", "=====formImage====\n" + bos.toString());
 return bos.toByteArray();
 }

 // Content-Type: multipart/form-data; boundary=----------8888888888888
 @Override
 public String getBodyContentType() {
 return MULTIPART_FORM_DATA + "; boundary=" + BOUNDARY;
 }
}

Instances


RequestQueue mQueue = SingleRequestQueue.getRequestQueue();

FormImage image;
if (imageUri != null) {
 Bitmap bitmap = null;
 try {//  Convert the path to bitmap
 bitmap=BitmapFactory.decodeStream(
  getContentResolver().openInputStream(imageUri));
 } catch (FileNotFoundException e1) {
 e1.printStackTrace();
 }
 image = new FormImage(bitmap);
} else
 image = null;

PostUploadRequest post = new PostUploadRequest(C.api.userIcon, null, image,
 new Response.Listener<JSONObject>() {
 @Override
 public void onResponse(JSONObject jsonObject) {
  try {
  //TODO
  } catch (JSONException e) {
  e.printStackTrace();
  }
 }
 }, new Response.ErrorListener() {
 @Override
 public void onErrorResponse(VolleyError error) {
  Log.e("VolleyError", error.getMessage(), error);
 }
 });

if (!customer.getCookie().equals("")) {
 //  Initiate to the server post Add on request cookie Field 
 post.setSendCookie(customer.getCookie());
}

mQueue.add(post);

Related articles: