Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

OkHttp框架二次封装,post json格式的参数(上)

$
0
0

OkHttp框架二次封装,post json格式的参数(上)

请求的封装

本篇主要是针对后台数据格式,进行请求参数的封装。封装的目的,是为了配合后台的数据结构,方便客户端进行数据的请求和响应数据的处理。

数据请求的格式

数据请求的请求以Json格式传递参数到服务器,在本例中,参数分为了公参和私参,请求体结构如下:

{
    "args": {
        "pri_args": {
            "username": "xxxxxx",  
            "password": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 
        },
        "pub_args": {        
            "appversion": "xxx",   
            "imei": "xxxxxxxx",  
            "token": "xxxxxxxx",   
            "uid": xxxxxx 
        }
    }
}

在使用过程时,首先要做的,是对参数的拼接,将私有参数和公参分开来,对于整个APP来说,只要登录了,每次请求接口时,公参都是相对固定的,因此可以把公参隐藏起来,让用户不必每次请求都自己写公参传进去,只需要在app打开的时候给公参赋值,然后对于每个接口,只需要传私参即可。

说在前面的话

项目使用的是鸿洋大神封装好的Okhttp-utils框架,针对Json格式的数据请求,进行了二次封装,膜拜大神!下面是原来的框架地址:
博客地址:http://blog.csdn.net/lmj623565791/article/details/47911083

github:https://github.com/hongyangAndroid/okhttp-utils

遵循开闭原则,二次封装并没有对原来的框架动刀子,只是把原来的框架作为依赖,在此基础上,进行了二次封装而已。

【Look here】:由于后台定义的请求格式各有不同,返回字段也各有差异,args、pri_args、pub_args等这些字段都不会一样,所以本文章封装的框架可能不能直接拿来就用,但是可以参照我这边封装的,照葫芦画瓢,本篇只介绍自己封装时的想法和写过之后的经验,谈不上技术分享,大家酌情参考。

参数的拼接

虽然原来的Okhttp-utils里并没有直接对json格式参数的封装,但是有对String类型参数的封装方法postString,我们可以借用这个方法,然后在这个方法里再封装一层,达到的效果是,使用时,传进去的是Map

    OkHttpUtils.postString().url(THost.HOST).content(paramContent).build().execute(callback);

使用时传入url和content,然后可以看到postString实际上是返回了一个PostStringBuilder类型的对象实例.

OkHttpUtils.java

public static PostStringBuilder postString() {
    return new PostStringBuilder();
}

然后通过这个对象的build方法,传入url和content参数,生成了一个RequestCall对象。

PostStingBuilder.java

 public RequestCall build() {
    return (new PostStringRequest(this.url, this.tag, this.params, this.headers, this.content, this.mediaType, this.id)).build();
}

OkHttpRequest.java

public RequestCall build() {
    return new RequestCall(this);
}

最后调用execute方法来发送请求,并且给这个方法传了两个参数,一个是刚刚生成的RequestCall对象,另一个就是自己定义的Callback了。

 public void execute(final RequestCall requestCall, Callback callback)
{
    ......
}

我们要做的工作是:
1、给框架使用者提供方法,来传入Map类型的参数;
2、转换传入的参数,将其变成json string
3、将得到的json string 通过postString方法发送出去

无论是传参还是转换,都可以在Builder里去写:

我们可以以PostStringBuilder类为模板新建一个PostJsonBuilder类:

public class TPostJsonBuilder extends OkHttpRequestBuilder<TPostJsonBuilder> {

private String paramContent;
private MediaType mediaType;

private Map<String, Object> pri_args;
private Map<String, Object> pub_args;

public TPostJsonBuilder() {
    this.pri_args = new HashMap<>() ;
    this.pub_args = new HashMap<>() ;
}

public TPostJsonBuilder(String paramContent, Map<String, Object> pri_args, MediaType mediaType, Map<String, Object> pub_args) {
    this.paramContent = paramContent;
    this.pri_args = pri_args;
    this.mediaType = mediaType;
    this.pub_args = pub_args;
}

public TPostJsonBuilder pri_args(Map<String, Object> args) {
    this.pri_args = args  ;
    return  this;
}
public TPostJsonBuilder pub_args(Map<String, Object> args) {
    this.pub_args = args  ;
    return  this;
}

public TPostJsonBuilder paramContent(String content) {
    if (content != null) {
        this.paramContent = content;
    } else if (this.pri_args.size() != 0 && this.pub_args.size() != 0){
        this.paramContent = initParams(this.pri_args,this.pub_args) ;
    } else {
        Exceptions.illegalArgument("args cannot be null !");
    }
    return this;
}
//这个方法就是拼接参数的关键了,将传入的公参和私参拼接成json string
private String initParams(Map<String, Object> pri_args, Map<String, Object> pub_args) {
    Map<String,Map<String, Object>> priArgs = new HashMap<>();
    priArgs.put("pri_args",pri_args);

    Map<String,Map<String, Object>> pubArgs = new HashMap<>();
    pubArgs.put("pub_args",pub_args);

    Map<String,Map<String,Map<String, Object>>> args = new HashMap<>() ;
    //将pub_args追加到pri_args里
    priArgs.putAll(pubArgs);
    args.put("args",priArgs);
    Gson g = new Gson();
    String argsStr = g.toJson(args) ;

    return argsStr ;
}


public TPostJsonBuilder mediaType(MediaType mediaType)
{
    this.mediaType = mediaType;
    return this;
}
@Override
public RequestCall build() {
    paramContent = initParams(this.pri_args,this.pub_args) ;
    mediaType = MediaType.parse("application/json;charset=utf-8") ;
    return new PostStringRequest(url,tag,params,headers,paramContent,mediaType,id).build();
}
}

里面将参数分为私参pri_args和公参pub_args两部分,并且给这个两个参数暴露了返回值为TPostJsonBuilder对象的方法,这样使用者就可以通过.pri_args(pri).pub_args(pub)来传入参数;
然后在关键的initParams方法里,将私参和公参拼接成服务器所需要的形式,然后再转成json string,在build方法里通过PostStringRequest构建RequestCall。这样参数的封装就基本完成了。

然后就是给使用者暴露postJson方法了,我们写一个类继承自OkHttpUtils:

TOkhttpUtil.java

public class TOkhttpUtil extends OkHttpUtils {


public static void initPubParams(Map<String, Object> pub_args) {
    TPublicParam.publicparam = pub_args ;
}
public static void initHeadS(String s) {
    TPublicParam.headparam.put("s",s) ;
}

public TOkhttpUtil(OkHttpClient okHttpClient) {
    super(okHttpClient);
}

public static TPostJsonBuilder postJson() { return  new TPostJsonBuilder(); }

}

里面有一个方法postJson,用来返回一个TPostJsonBuilder对象。
还有两个方法,initPubParams和initHeadS,这两个方法就是对于公参和请求头的封装了。本例中,请求头里有2个字段,s字段相对不变,m字段每个接口都不同,所以可以先封装好s,下面会说到。

这样TOkhttUtil就可以这么使用了:

TOkhttpUtil.postJson().url(THost.HOST).pri_args(pri_args).pub_args(pub_args).build().execute(callback)

其中的pri_args和pub_args分别是要传的公参和私参,例如:

Map<String,Object> pri_args = new HashMap<>();
pri_args.put("username","张三");
pri_args.put("password","4f32d39b42v322vkj43");

Map<String,Object> pub_args = new HashMap<>();
pub_args.put("appversion","1.0.1");
pub_args.put("imei","0000-0033-3300-3232-9909-3333");
pub_args.put("token","4f32d39b42v322vkj43");
pub_args.put("uid",9527);

就可以得到文章开头所要传的参数格式。

参数的封装

虽然能请求了,但是公参里面的值大多不变,每次调用方法都要传pub_args也不好,所以还是可以通过封装参数,然后暴露多个重载方法,
让用户用的更省心:

TBaseApi.java

public class TBaseApi {

//最原始的方法,传url,请求头,私参,公参,回调
public static void createPostRequest(String url, Map<String,String> heads, Map<String,Object> pri_args, Map<String,Object> pub_args, TBaseCallback callback){
    TOkhttpUtil.postJson()
        .url(url)
        .headers(heads)
        .pri_args(pri_args)
        .pub_args(pub_args)
        .build()
        .execute(callback) ;
}
//封装了公参,使用时不用传公参了。
public static void createPostRequest(String url, Map<String,String> heads, Map<String,Object> pri_args, TBaseCallback callback){
    TOkhttpUtil.postJson()
            .url(url)
            .headers(heads)
            .pri_args(pri_args)
            .pub_args(TPublicParam.publicparam)
            .build()
            .execute(callback) ;
}
//使用固定的HOST
public static void createPostRequest(Map<String,String> heads, Map<String,Object> pri_args, TBaseCallback callback){
    TOkhttpUtil.postJson()
            .url(THost.HOST)
            .headers(heads)
            .pri_args(pri_args)
            .pub_args(TPublicParam.publicparam)
            .build()
            .execute(callback) ;
}
//封装请求头里面的s字段,只需传m字段就行了。
public static void createPostRequest(String headM, Map<String,Object> pri_args, TBaseCallback callback){
    TOkhttpUtil.postJson()
            .url(THost.HOST)
            .headers(TPublicParam.addHeadM(headM))
            .pri_args(pri_args)
            .pub_args(TPublicParam.publicparam)
            .build()
            .execute(callback);

}
}

上面的方法里,提供了多个选择,TPublicParam里封装好了公参。在使用的时候,只需要在初始化的时候,同时把固定的公参和私参也加进去:

比如在TApplication.java里初始化:

OkHttpClient client = new OkHttpClient.Builder()
            .connectTimeout(10*1000L, TimeUnit.MILLISECONDS)
            .readTimeout(10*1000L, TimeUnit.MILLISECONDS)
            .build();
TOkhttpUtil.initClient(client) ;
  TOkhttpUtil.initPubParams(TPublicParam.addPublicParams(pubParams));
TOkhttpUtil.initHeadS(TConstants.getS());

这样,以后在调用时,可以只传最低限度的参数,比如请求头的m字段,私参,和自定义的callback,已经封装好的头部的s字段和公参就不需要操心了。

比如:

Map<String,Object> pri_args = new HashMap();
TBaseCallback callback = new ....
TBaseApi.createPostRequest("getUserInfo",pri_args,callback) ;

下篇里会介绍响应的封装,以及TBaseCallback是什么。有兴趣可以看看下篇:
http://blog.csdn.net/black_dreamer/article/details/53068627

github地址:https://github.com/herdotage/Android_sample/tree/master/LOkhttpUtils

作者:black_dreamer 发表于2016/11/7 18:05:56 原文链接
阅读:8 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>