使用 Android OkHttp网络请求时,关于传参数的注意事项

近期我在项目里使用了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







猜你喜欢

转载自blog.csdn.net/liu_guizhou/article/details/64519589