Android使用Volley框架定制PostUploadRequest上传文件
时间:2022-07-28
本文章向大家介绍Android使用Volley框架定制PostUploadRequest上传文件,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
发现问题
项目中有发表动态的功能,该功能可以将文本和图片上传至服务器。 Volley通过定制PostUploadRequest实现文件上传的功能,本文以一张图片上传为例。
数据格式
以下为项目中图片上传实例的数据格式 多张图片上传可通过添加——WebKitFormBoundary 内容实现
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"
发表的圈子内容
------WebKitFormBoundaryzayymBT8Owg2UzBR
Content-Disposition: form-data; name="file"; filename="这里是文件名"
Content-Type: image/png
这里空一行 接下来是二进制图片文件内容
------WebKitFormBoundaryzayymBT8Owg2UzBR--
这里为空白的一行
总共有加上结尾行,有五行,图片的二进制数,整个算一行;下面来分析下:
1、第一行:”–” + boundary + “rn” ; 文件上传在提交数据的开始标志不变;
2、第二行:Content-Disposition: form-data; name=”参数的名称”; filename=”上传的文件名” + “rn”
3、第三行:Content-Type: 文件的 mime 类型 + “rn” 这一行是文件上传必须要的,而普通的文字提交可有可无,mime 类型需要根据文档查询;
4、第四行:”rn”
5、第五行文件的二进制数据 + “rn”: 结尾行:”–” + boundary + “–” + “rn” 可以同时上传多个文件,上传多个文件的时候重复1、2、3、4、5步,在最后的一个文件的末尾加上统一的结束行。
上传的图像实体类
import java.io.ByteArrayOutputStream;
import android.graphics.Bitmap;
/*
* 上传的图像实体类
* */
public class FormImage {
// 参数的名称
private String mName;
// 文件名
private String mFileName;
// 文件的 mime,需要根据文档查询
private String mMime;
// 需要上传的图片资源,因为这里测试为了方便起见,直接把 bitmap 传进来,真正在项目中一般不会这般做,
// 而是把图片的路径传过来,在这里对图片进行二进制转换
private Bitmap mBitmap = null;
public FormImage(Bitmap bitmap) {
this.mBitmap = bitmap;
}
public String getName() {
return "file";
}
public String getFileName() {
return "add.png";
}
// 对图片进行二进制转换
public byte[] getValue() {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
mBitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos);
return bos.toByteArray();
}
// 因为我知道是 png 文件,所以直接根据文档查的
public String getMime() {
return "image/png";
}
}
定制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;
/*
* 发送文件的volley
* post请求 Cookie
* */
public class PostUploadRequest extends Request<JSONObject {
private Map<String, String sendHeader = new HashMap<String, String ();
// 正确数据的时候回掉用
private Response.Listener<JSONObject mListener;
// 请求 数据通过参数的形式传入
private String content;
private FormImage mImage;
// 数据分隔线
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;
// 设置请求的响应事件,因为文件上传需要较长的时间,所以在这里加大了,设为5秒
setRetryPolicy(new DefaultRetryPolicy(5000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
}
/*
* 这里开始解析数据
* @param response
* Response from the network
* @return
* */
@Override
protected Response<JSONObject parseNetworkResponse(NetworkResponse response) {
try {
// 防止中文乱码
@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));
}
}
/*
* 回调正确的数据
* @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) {
/**
* 图片
*/
/* 第一行 */
// `"--" + BOUNDARY + "rn"`
sb.append("--" + BOUNDARY + "rn");
/* 第二行 */
// Content-Disposition: form-data; name="参数的名称"; filename="上传的文件名" +
// "rn"
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("rn");
/* 第三行 */
// Content-Type: 文件的 mime 类型 + "rn"
sb.append("Content-Type: ");
sb.append(mImage.getMime());
sb.append("rn");
/* 第四行 */
// "rn" 空白的一行
sb.append("rn");
try {
bos.write(sb.toString().getBytes("utf-8"));
/* 第五行 */
// 文件的二进制数据 + "rn"
bos.write(mImage.getValue());
bos.write("rn".getBytes("utf-8"));
} catch (IOException e) {
e.printStackTrace();
}
/* 结尾行 */
// `"--" + BOUNDARY + "--" + "rn"`
String endLine = "--" + BOUNDARY + "--" + "rn";
try {
bos.write(endLine.toString().getBytes("utf-8"));
} catch (IOException e) {
e.printStackTrace();
}
Log.v("upLoad", "=====formImage====n" + bos.toString());
return bos.toByteArray();
}
/**
* 文字
*/
/* 第一行 */
// `"--" + BOUNDARY + "rn"`
sb.append("--" + BOUNDARY + "rn");
/* 第二行 */
// Content-Disposition: form-data; name="text" + "rn"
sb.append("Content-Disposition: form-data;");
sb.append(" name="");
sb.append("text");
sb.append(""");
sb.append("rn");
/* 第三行 */
// "rn" 空白的一行
sb.append("rn");
/* 第四行 */
// 文本内容
sb.append(content);
sb.append("rn");
if (mImage == null) {
/* 结尾行 */
// `"--" + BOUNDARY + "--" + "rn"`
String endLine = "--" + BOUNDARY + "--" + "rn";
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 {
/**
* 图片
*/
/* 第一行 */
// `"--" + BOUNDARY + "rn"`
sb.append("--" + BOUNDARY + "rn");
/* 第二行 */
// Content-Disposition: form-data; name="参数的名称"; filename="上传的文件名" +
// "rn"
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("rn");
/* 第三行 */
// Content-Type: 文件的 mime 类型 + "rn"
sb.append("Content-Type: ");
sb.append(mImage.getMime());
sb.append("rn");
/* 第四行 */
// "rn" 空白的一行
sb.append("rn");
try {
bos.write(sb.toString().getBytes("utf-8"));
/* 第五行 */
// 文件的二进制数据 + "rn"
bos.write(mImage.getValue());
bos.write("rn".getBytes("utf-8"));
} catch (IOException e) {
e.printStackTrace();
}
}
/* 结尾行 */
// `"--" + BOUNDARY + "--" + "rn"`
String endLine = "--" + BOUNDARY + "--" + "rn";
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;
}
}
实例
RequestQueue mQueue = SingleRequestQueue.getRequestQueue();
FormImage image;
if (imageUri != null) {
Bitmap bitmap = null;
try {// 将路径转化成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("")) {
// 向服务器发起post请求时加上cookie字段
post.setSendCookie(customer.getCookie());
}
mQueue.add(post);
以上就是本文的全部内容,希望对大家的学习有所帮助。
- 分布式监控系统Zabbix3.2跳坑指南
- 一图看懂java内存模型
- 零代码如何打造自己的实时监控预警系统
- 一步一步在Windows中使用MyCat负载均衡 上篇
- 你真的会玩SQL吗?之逻辑查询处理阶段
- javascript中如何正确将日期(Date)字符串转换为日期(Date)对象?
- 全面迎接.Net3.0时代的到来(WCF/WF/WPF/LINQ)
- SQL Server 2005 正则表达式使模式匹配和数据提取变得更容易
- [基础]datagridview绑定数据源的几种常见方式
- c#:winform鼠标拖动窗口大小时,设定窗口最小尺寸
- 在非SqlServer数据库上实现MemberShip和Role功能(自定义MemberShipProvider和RoleProvider)
- 一种实用的表格行鼠标点击高亮效果
- Lucene:QueryParser中操作符的疑惑
- 利用Boost影响Lucene查询结果的排序
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- PHP递归的三种常用方式
- python实现xlwt xlrd 指定条件给excel行添加颜色
- PHP解析url并得到url参数方法总结
- TP5(thinkPHP5框架)基于bootstrap实现的单图上传插件用法示例
- PHP实现微信小程序用户授权的工具类示例
- thinkphp5.0整合phpsocketio完整攻略(绕坑)
- Yii2框架自定义类统一处理url操作示例
- tp5(thinkPHP5框架)captcha验证码配置及验证操作示例
- PHP htmlspecialchars_decode()函数用法讲解
- ThinkPHP中获取指定日期后工作日的具体日期方法
- php curl操作API接口类完整示例
- PHP使用PDO创建MySQL数据库、表及插入多条数据操作示例
- Python叠加矩形框图层2种方法及效果
- PHP常量define和const的区别详解
- 解决运行出现'dict' object has no attribute 'has_key'问题