Volley的使用(二)
来源:互联网 发布:圣和圣静安公馆 知乎 编辑:程序博客网 时间:2024/05/24 06:19
上一篇Volley的使用(一)介绍了Volley的基本使用,今天看一看如何提交表单
一.表单提交的数据格式
Connection: keep-aliveContent-Length: 123X-Requested-With: ShockwaveFlash/16.0.0.296User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.93 Safari/537.36Content-Type: multipart/form-data; boundary=----------Ij5ei4KM7KM7ae0KM7cH2ae0Ij5Ef1Accept: */*Accept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.8Cookie: bdshare_firstime=1409052493497------------Ij5ei4KM7KM7ae0KM7cH2ae0Ij5Ef1Content-Disposition: form-data; name="position"1425264476444------------Ij5ei4KM7KM7ae0KM7cH2ae0Ij5Ef1Content-Disposition: form-data; name="editorIndex"ue_con_1425264252856------------Ij5ei4KM7KM7ae0KM7cH2ae0Ij5Ef1Content-Disposition: form-data; name="cm"100672------------Ij5ei4KM7KM7ae0KM7cH2ae0Ij5Ef1--
看到上面的数据包,我们不需要全部分析,我们主要关心的是数据如何封装,因为http请求头,在网络请求中已经为我们封装好了;可以看到这里总共是提交了三条数据,每一条数据的格式都是一样的,所以我们只需要分析一条数据即可,这里拿最后一条数据来说,因为在所有的数据之后还有一个结尾的标志。
------------Ij5ei4KM7KM7ae0KM7cH2ae0Ij5Ef1Content-Disposition: form-data; name="cm"100672------------Ij5ei4KM7KM7ae0KM7cH2ae0Ij5Ef1--
这条数据一共有四行,加上最后的结尾标识符一共有五行,
1.第一行
"-"+boundary+"/r/n"
说明:”–”为数据开始标志,boundary为http实体头定义的边界分割线,boundary可以是任意的字符串,只要和Content-Type: multipart/form-data; boundary=———-Ij5ei4KM7KM7ae0KM7cH2ae0Ij5Ef1中保持一直即可,”\r\n”为回车换行;
2.第二行
Content-Disposition: form-data; name="参数名"+/r/n"
说明:Content-Disposition表示上传的内容特性,form-data上传内容特性为表单的形式
3.第三行
"/r/n"
说明:这是一个空行,只有一个回车换行 ;
4.第四行
"参数的值"+"/r/n"
说明:每个参数都是由一个key和value组成,而这一行就是value跟回车换行符
5.结束行
"-"+boundary+"-"+"/r/n"
说明:在所有的数据结束之后,需要有这个结尾标志。
如果有多个参数,则重复1、2、3、4,直至最后一个参数的最后加上结尾行。
参数实体类
这里对参数做一个封装,因为往往提交表单的时候,都需要提交多个参数
public class FormText { private String mName; private String mValue; public FormText(String name, String value){ this.mName = name; this.mValue = value; } public String getmName() { return mName; } public void setmName(String mName) { this.mName = mName; } public String getmValue() { return mValue; } public void setmValue(String mValue) { this.mValue = mValue; }}
接下来要重写一个方法
@Overridepublic byte[] getBody() throws AuthFailureError { if(mItemList==null||mItemList.size()==0){ System.out.println("==========null"); return super.getBody(); } ByteArrayOutputStream bos = new ByteArrayOutputStream(); int size = mItemList.size(); FormText formText; for (int i = 0; i < size; i++) { formText = mItemList.get(i); //第一行 "-"+boundary+"/r/n" StringBuilder sb = new StringBuilder(); sb.append("--"+BOUNDARY); sb.append("\r\n"); //第二行 Content-Disposition: form-data; name="参数名"+/r/n" sb.append("Content-Disposition: form-data;"); sb.append("name=\""); sb.append(formText.getmName()); sb.append("\""); sb.append("\r\n"); //第三行 "/r/n" sb.append("\r\n"); //第四行 "参数的值"+"\r\b" sb.append(formText.getmValue()); sb.append("\r\n"); System.out.println("=========sb"+sb.toString()); try { bos.write(sb.toString().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(); } return bos.toByteArray();}
可以看到,这个方法的实现,就是对数据按照我们所分析的格式组装。
在 Request 中还有一个关键的地方,需要在 http 头部中声明内容类型为表单数据
Content-Type: multipart/form-data; boundary=----------8888888888888
所以的重写下面方法为
/** * 获取内容类型,这里为表单类型 * @return */ @Override public String getBodyContentType() { return MULTIPART_FORM_DATA+": boundary="+BOUNDARY; }
所以
public class PostFormRequest<T> extends Request { private List<FormText> mItemList; private Type mClazz; private ResponseListener mListener; private Gson mGson; private String BOUNDARY = "---------8888888"; private String MULTIPART_FORM_DATA = "multipart/form-data"; public PostFormRequest(String url, List<FormText> itemList, Type type, ResponseListener listener) { super(Method.POST, url, listener); this.mItemList = itemList; this.mClazz = type; this.mListener = listener; mGson = new Gson(); } @Override protected Response parseNetworkResponse(NetworkResponse response) { try { T result; String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers)); System.out.println("========json: "+jsonString); result = mGson.fromJson(jsonString,mClazz); return Response.success(result,HttpHeaderParser.parseCacheHeaders(response)); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return Response.error(new ParseError()); } @Override protected void deliverResponse(Object response) { mListener.onResponse(response); } @Overridepublic byte[] getBody() throws AuthFailureError { if(mItemList==null||mItemList.size()==0){ System.out.println("==========null"); return super.getBody(); } ByteArrayOutputStream bos = new ByteArrayOutputStream(); int size = mItemList.size(); FormText formText; for (int i = 0; i < size; i++) { formText = mItemList.get(i); //第一行 "-"+boundary+"/r/n" StringBuilder sb = new StringBuilder(); sb.append("--"+BOUNDARY); sb.append("\r\n"); //第二行 Content-Disposition: form-data; name="参数名"+/r/n" sb.append("Content-Disposition: form-data;"); sb.append("name=\""); sb.append(formText.getmName()); sb.append("\""); sb.append("\r\n"); //第三行 "/r/n" sb.append("\r\n"); //第四行 "参数的值"+"\r\b" sb.append(formText.getmValue()); sb.append("\r\n"); System.out.println("=========sb"+sb.toString()); try { bos.write(sb.toString().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(); } return bos.toByteArray();}
接下来提交
public class TestApi { public static void performFormApi(String url,ResponseListener listener){ List<FormText> formTextList = new ArrayList<>(); formTextList.add(new FormText("api_key",Constant.API_KEY)); Request request = new PostFormRequest<MovieInfo>(url,formTextList,new TypeToken<MovieInfo>(){}.getType(),listener); VolleyUtil.getRequestQueue().add(request); }}
通过以上内容我们不难发现,表单提交就是把文本通过二进制的形式传给服务器,从而得到对应的响应,这篇 blog 其实也算是一篇过度的文章,因为一般我们不会这么提交文字数据,而是通过我们上一篇 blog 中的post 请求的方式,那什么时候我们需要用到表单提交呢,当表单中含有附件,如图片,视频等文件的的时候;这也就是我们下一篇 blog 要讲的:Volley的使用(三)。
- Volley的使用(二)
- Volley的使用(二)
- volley的使用(二)
- Android Volley框架的使用(二)
- Volley 的介绍和使用(二)
- Android Volley框架的使用(二)
- Volley的使用(二) post请求
- Volley使用小结二
- Volley框架(二):使用Volley加载图片
- Volley使用笔记(二)
- Android Volley框架使用(二)
- Android Volley框架使用(二)
- Android中关于Volley的使用(二)从RequestQueue开始来深入认识Volley
- Android Volley网络通信框架的使用(二):Volley加载网络图片
- Volley的使用以及源码分析(二)
- Volley的使用以及源码分析(二)
- Volley的使用(二):加载网络图片
- 开源框架Volley的使用《二》[NetWorkImageView&&LruCache&ImageLoader]
- UVA 1099 Sharing Chocolate - 状压dp
- php7如何加入环境变量
- 改进的经纬度最短路径
- 第三次上机实践项目-项目4-(2)
- 21. Merge Two Sorted Lists
- Volley的使用(二)
- iOS App国际化
- js 实现实时时钟
- linux用户管理命令
- Parsing Data for android-N failed Unsupported major.minor version 51.0
- spring 在Thread中注入@Resource失败,总为null~解决
- JAVA设计模式之单例模式
- 关于dropdowndatawindow的几个说明
- SciTE 编辑器汉化