欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android使用Volley框架定制PostUploadRequest上传文件

程序员文章站 2022-07-04 09:54:06
发现问题 项目中有发表动态的功能,该功能可以将文本和图片上传至服务器。 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 + “\r\n” ;
文件上传在提交数据的开始标志不变;

2、第二行:content-disposition: form-data; name=”参数的名称”; filename=”上传的文件名” + “\r\n”

3、第三行:content-type: 文件的 mime 类型 + “\r\n”
这一行是文件上传必须要的,而普通的文字提交可有可无,mime 类型需要根据文档查询;

4、第四行:”\r\n”

5、第五行文件的二进制数据 + “\r\n”:
结尾行:”–” + boundary + “–” + “\r\n”
可以同时上传多个文件,上传多个文件的时候重复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 + "\r\n"`
  sb.append("--" + boundary + "\r\n");

  /* 第二行 */
  // content-disposition: form-data; name="参数的名称"; filename="上传的文件名" +
  // "\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");

  /* 第三行 */
  // content-type: 文件的 mime 类型 + "\r\n"
  sb.append("content-type: ");
  sb.append(mimage.getmime());
  sb.append("\r\n");

  /* 第四行 */
  // "\r\n" 空白的一行
  sb.append("\r\n");

  try {
  bos.write(sb.tostring().getbytes("utf-8"));
  /* 第五行 */
  // 文件的二进制数据 + "\r\n"
  bos.write(mimage.getvalue());
  bos.write("\r\n".getbytes("utf-8"));
  } catch (ioexception e) {
  e.printstacktrace();
  }

  /* 结尾行 */
  // `"--" + 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();
 }
 /**
  * 文字
  */
 /* 第一行 */
 // `"--" + boundary + "\r\n"`
 sb.append("--" + boundary + "\r\n");

 /* 第二行 */
 // 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");

 /* 第三行 */
 // "\r\n" 空白的一行
 sb.append("\r\n");

 /* 第四行 */
 // 文本内容
 sb.append(content);
 sb.append("\r\n");

 if (mimage == null) {
  /* 结尾行 */
  // `"--" + 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 {
  /**
  * 图片
  */
  /* 第一行 */
  // `"--" + boundary + "\r\n"`
  sb.append("--" + boundary + "\r\n");

  /* 第二行 */
  // content-disposition: form-data; name="参数的名称"; filename="上传的文件名" +
  // "\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");

  /* 第三行 */
  // content-type: 文件的 mime 类型 + "\r\n"
  sb.append("content-type: ");
  sb.append(mimage.getmime());
  sb.append("\r\n");

  /* 第四行 */
  // "\r\n" 空白的一行
  sb.append("\r\n");

  try {
  bos.write(sb.tostring().getbytes("utf-8"));
  /* 第五行 */
  // 文件的二进制数据 + "\r\n"
  bos.write(mimage.getvalue());
  bos.write("\r\n".getbytes("utf-8"));
  } catch (ioexception e) {
  e.printstacktrace();
  }

 }

 /* 结尾行 */
 // `"--" + 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;
 }
}

实例

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。