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