美文网首页
记录项目中的Retrofit请求参数封装

记录项目中的Retrofit请求参数封装

作者: 写代码的解先生 | 来源:发表于2017-08-16 20:23 被阅读1704次

    项目中联网框架使用的是Retrofit2,因为项目的接口设计了许多公共参数,需要对Retrofit网络请求参数进行进一步的封装。本文记录了参数封装的过程。

    说在前面的话:由于每个公司的接口设计规则不同,这里的封装代码也会千差万别。

    文章中项目的接口规则为:统一采用POST表单的方式提交到服务器,服务器返回JSON格式的数据。并且设置了公共参数,每次请求需要携带公共参数,并且添加公共的头部。

    Step1

    刚开始看到表单方式,觉得很激动,Retrofit2 支持 @FormUrlEncoded注解的方式来进行表单访问
    所以就有了这样的Retrofit 接口设计

    
    public interface ApiService {
    
        @FormUrlEncoded
        @POST("login")
        Observable<BaseResult<String>> login(@Field("data") String json);
    }
    

    因为只有@Body注解的参数才能 被Converter 转换,所以这里方法的参数使用的String类型

    接下来就是公共参数的设置,采用 拦截器的方式来完成

    public class HttpParamInterceptor implements Interceptor {
    
        @Override
        public Response intercept(Chain chain) throws IOException {
    
            Request request = chain.request();
            Request.Builder requestBuilder = request.newBuilder();
            //添加公共的头部
            requestBuilder.addHeader("User-Agent", "pinxiango");
            
            String method = request.method(); 
            //接口规则规定了请求方式为 Form 表单,这里只对Post进行处理
            if ("POST".equals(method)) {  //POST 请求
                RequestBody body = request.body();
    
                //因为我们项目需要获取参数 进行进一步处理,需要将参数记录下来
                String data_json = ""; //传入的Json 字符串
    
                FormBody.Builder builder = new FormBody.Builder();
    
                FormBody formBody = (FormBody) body;
    
               int size = formBody.size();
                if (size == 0) {
                        builder.add("data", data_json);
               } else {
                    //循环将传入的 表单添加到新的表单
                    for (int i = 0; i < size; i++) {
                          String name = formBody.name(i);
                          String value = formBody.value(i);
                          if ("data".equals(name)) {
                                data_json = value;
                            }
                            builder.add(name, value);
                       }
                  }
                } 
             
    
                String sign = Contacts.KEY + "-" +
                        Contacts.version + "-" +
                        Contacts.app_source + "-" +
                        data_json;
              //拼接 公共的参数
                
              
                builder.add("datetime", dateTime + "");
                builder.add("sign", sign);
    
    
                FormBody formBody = builder.build();
                //重新构建 request
                request = requestBuilder
                        .post(formBody)
                        .build();
            }
    
            return chain.proceed(request);
        }
    
    }
    

    嗯?开始愉快的使用了,用了一圈发现怎么感觉那里不对

    haha
    • Retrofit 对于@FormUrlEncoded注解的Post请求不支持空参数的请求

    • 每次请求需要手动转成 Json 字符串(尤其是这一步操作,深恶痛绝)
      为了解决这个问题,对ApiService 和HttpParamInterceptor进行修改

    public interface ApiService {
    
    
        @POST("login")
        Observable<BaseResult<String>> login(@Body User user);
    
        @POST("logout")
        Observable<BaseResult<String>> logout();
    }
    

    接口设计注解全部采用 @POST的形式,需要Json 数据可以直接采用@Body 的形式 ,Converter会将其转换为Json 字符串

    修改后HttpParamInterceptor 代码如下

    public class HttpParamInterceptor implements Interceptor {
    
        @Override
        public Response intercept(Chain chain) throws IOException {
    
            Request request = chain.request();
            Request.Builder requestBuilder = request.newBuilder();
            //添加公共的头部
            requestBuilder.addHeader("User-Agent", "pinxiango");
    
    
            String method = request.method();
            if ("POST".equals(method)) {  //POST 请求
                RequestBody body = request.body();
    
                String data_json = ""; //传入的Json 字符串
    
                //后台规定数据格式为 Form 表单形式
                FormBody.Builder builder = new FormBody.Builder(); 
    
                //由于采用的是 普通的@Post 形式
                //并且经过Converter 的转换,内容为Json字符串
                //这里直接进行读取
                Buffer buffer = new Buffer();
                body.writeTo(buffer);
                data_json = buffer.readUtf8();
                builder.add("data", data_json);
    
                //系统当前的时间戳
                int dateTime = (int) (new Date().getTime() / 1000);
               
    
                String mde_sign = Contacts.KEY + "-" +
                       data_json + "-" +
                        dateTime;
                builder.add("datetime", dateTime + "");
                builder.add("sign", mde_sign);
    
                //构建Form 表单
                FormBody formBody = builder.build();
                //重构请求
                request = requestBuilder
                        .post(formBody)
                        .build();
            }
    
            return chain.proceed(request);
        }
    
    }
    

    至此,参数的封装结束。可以参考以上代码 进行分页请求的分装

    相关文章

      网友评论

          本文标题:记录项目中的Retrofit请求参数封装

          本文链接:https://www.haomeiwen.com/subject/rbrwrxtx.html