xutils3.0 post请求网络遇到的那些坑
最近公司项目比较赶,所以直接用了一个集成的xutils3.0。跟php的同事对接口的时候发现,用网上的post案例请求数据的时候,php端无法接收到数据,但是ios端post的数据php是可以接收到的。百度了半天没有百度出答案,后来自己瞎搞发现了点眉目,现在分享出来给后人~~~
原因:
提交表单的方式有以下几种:
因为xutils3.0用的是raw的方式来提交post请求的,而php后台因为要兼顾web前台,所以用了form-data的方式来接收,所以无法接收到x.http.post()过去的数据,所以php就拿不到Android客户端post过去的数据。
ps:百度的时候也百度过以前的人问过这样的问题,但是一直没有人解答,可惜,如:http://www.eoeandroid.com/thread-918169-1-2.html?_dsign=c6564c7f
解决:
xutils3.0中提供一个接口来改变提交表单的方式:
RequestParams.setRequestBody(RequestBody requestBody)
/** * 发送post请求,使用map数据,使用application/x-www-form-urlencoded提交表单 * @param <T> */ public static <T> Callback.Cancelable postByMapPlus(String url,Map<String,String> map,HttpCallback<T> callback){ RequestParams params=new RequestParams(url); params = addHeader(params); try { params.setRequestBody(new UrlEncodedParamsBody(map,"utf-8")); } catch (IOException e) { e.printStackTrace(); } //LogUtil.d_http("postByMap Head: " + Arrays.toString(params.getHeaders().toArray())); //LogUtil.d_http("postByMap: " + params.toString()); Callback.Cancelable cancelable = x.http().post(params, callback); return cancelable; }
public class UrlEncodedParamsBody implements RequestBody { private byte[] content; private String charset = "UTF-8"; public UrlEncodedParamsBody(Map<String,String> map, String charset) throws IOException { if (!TextUtils.isEmpty(charset)) { this.charset = charset; } StringBuilder contentSb = new StringBuilder(); if(null!=map){ for(Map.Entry<String, String> entry : map.entrySet()) { String name = entry.getKey(); String value = entry.getValue(); if (!TextUtils.isEmpty(name) && value != null) { if (contentSb.length() > 0) { contentSb.append("&"); } contentSb.append(Uri.encode(name, this.charset)) .append("=") .append(Uri.encode(value, this.charset)); } } } this.content = contentSb.toString().getBytes(this.charset); } @Override public long getContentLength() { return content.length; } @Override public void setContentType(String contentType) { } @Override public String getContentType() { return "application/x-www-form-urlencoded;charset=" + charset; } @Override public void writeTo(OutputStream sink) throws IOException { sink.write(this.content); sink.flush(); } }
Form表单语法