近期我在项目里使用了okhttp网络请求框架,由于这个框架不能直接应用于项目,但是本人比较懒,又不想去封装,所以就是用了鸿洋大神封装好的库,下面是有关库的连接: 点击打开链接https://github.com/hongyangAndroid/okhttp-utils。那接下来,我就说一说怎么使用,以及我遇到的问题吧!
首先,我使用了post的请求方式,代码如下:
OkHttpUtils
.postString()
.url(url)
.mediaType(MediaType.parse("application/json; charset=utf-8"))
.content(jsonString)
.build()
.execute(new Callback());
在上面,我们把请求参数放进Map,然后在转换成json串,放在.content(“入参数”)进行请求。然而这种请求方式,是把请求入参放在RequestBody里进行构建Request请求体,如以下相关代码说明:
@Override
protected RequestBody buildRequestBody()
{
return RequestBody.create(mediaType, content);
}
@Override
protected Request buildRequest( RequestBody requestBody)
{
return builder.post(requestBody).build();
}
以及相关它的逻辑:
public static RequestBody create(MediaType contentType, String content) {
Charset charset = Util.UTF_8;
if (contentType != null) {
charset = contentType.charset();
if (charset == null) {
charset = Util.UTF_8;
contentType = MediaType.parse(contentType + "; charset=utf-8");
}
}
byte[] bytes = content.getBytes(charset);
return create(contentType, bytes);
}
/** Returns a new request body that transmits {@code content}. */
public static RequestBody create(final MediaType contentType, final byte[] content) {
return create(contentType, content, 0, content.length);
}
/** Returns a new request body that transmits {@code content}. */
public static RequestBody create(final MediaType contentType, final byte[] content,
final int offset, final int byteCount) {
if (content == null) throw new NullPointerException("content == null");
Util.checkOffsetAndCount(content.length, offset, byteCount);
return new RequestBody() {
@Override public MediaType contentType() {
return contentType;
}
@Override public long contentLength() {
return byteCount;
}
@Override public void writeTo(BufferedSink sink) throws IOException {
sink.write(content, offset, byteCount);
}
};
}
protected abstract RequestBody buildRequestBody();
protected RequestBody wrapRequestBody(RequestBody requestBody, final Callback callback)
{
return requestBody;
}
protected abstract Request buildRequest(RequestBody requestBody);
public RequestCall build()
{
return new RequestCall(this);
}
public Request generateRequest(Callback callback)
{
RequestBody requestBody = buildRequestBody();
RequestBody wrappedRequestBody = wrapRequestBody(requestBody, callback);
Request request = buildRequest(wrappedRequestBody);
return request;
}
但是通过上面的这种传参数的方式,始终得不到正常的访问接口请求,返回的数据,只有格式,但是内容不是空的就是错误的结果!如下显示:
{
"checkData": "8CA87ED527671330949792CE226B5804",
"code": "9003",
"data": {
"code": "0000",
"resultData": { null
},
"resultMsg": ""
},
"error": [],
"msg": "未知错误,请联系管理员",
"signature": "391B7B1A60179A5B18DA4EE9B988CD7A",
"v": "1"
}
就这样传参数,试了多次还是不行;最后没办法就去找了后端的同学帮忙一起调试看看,结果他说,我把入参都放在 RequestBody里面了,但是 他们后端取参数的时候,是通过 request.getParameter("data")来获取客户端的请求参数的,也就是说,我传递的参数他们根本就没有接收到,那怎恶魔会返回给我正确的参数呢?后台同学还特意为我查看了后端入参的日志,如下:
head部分
org.apache.tomcat.util.http.NamesEnumerator@eddb064
content-type:application/x-www-form-urlencoded
content-length:307
host:195.29.556.244:9080
connection:Keep-Alive
accept-encoding:gzip
user-agent:okhttp/3.4.1
body部分:
data:{"a":{"deviceUUID":"359786056453385","string":435889360},"b":{"objectNo":"100201201609051722312991751659096335","objectType":"5",
"userId":"100401201609021237044627442435699555","userType":"1"},"c":{}}
好的,既然找到问题所在那就好解决了,我告诉他,我换一种方式传参数给他,试试,代码如下:
OkHttpUtils
.post()
.url(url)
.addParams("data", "jsonString")
.build()
.execute(new Callback());
我们乍一看,和第一种请求方式差不多,但是其实他们封装请求参数的方式确实有区别的,具体代码如下:
@Override
protected RequestBody buildRequestBody()
{
FormBody.Builder builder = new FormBody.Builder();
addParams(builder);
FormBody formBody = builder.build();
return formBody;
}
private void addParams(FormBody.Builder builder)
{
if (params != null)
{
for (String key : params.keySet())
{
builder.add(key, params.get(key));
}
}
}
从上面代码可以看出,这是通过FormBody.Builder的builder这个对象构建的输入参数,而第一种方式则是通过RequestBody.create(mediaType, content);来处理的客户端入参数;由此可以看出,两种不同的传参数的方式,到那时后端只进行了一种方式的处理,所以请求接口得不到想要的 结果了。这里我们使用第二种方式 使用 builder构建输入参数得到正确的请求结果了,如下显示:
{
"checkData": "8CA87ED527671330949792CE226B5804",
"code": "0000",
"data": {
"code": "0000",
"resultData": {
"expiration": 7776000,
"authToken": "7D5C411A8A656285ADBD5A1889B299DA"
},
"resultMsg": "调用成功"
},
"error": [],
"msg": "",
"signature": "391B7B1A60179A5B18DA4EE9B988CD7A",
"v": "1"
}
在这里很感谢后端那位小伙伴的一下午的 帮忙调试!当然还要感谢鸿洋 大神的这个开源库,让我们使用的很开心!本文只作为开发记录,不是什么什么技术文章,水平有限,多谢批评指正,大家一起学习!!!
参考连接:http://blog.csdn.net/lmj623565791/article/details/49734867