Okhttp设置公共参数,以json对象放入@Body请求公共参数的配置方式

当网络请求都是基于一个URL,所有的接口都是同一个地址,而请求不同接口数据则是通过command字段进行配置,然后所有的请求参数都是需要自己写一个bean类,再转成json格式放入请求body里发给后台,而不是通过表单form-body发送,所以配置一些公共参数,如sessionId、timestamp等就有点麻烦,每个bean类都要加这些参数,或者写个基类BaseRequestBean,基类当中配置公共参数,这是一种解决方案,但我不想这么做,那么只能通过okhttp配置拦截器设置公共参数;以下进入主题:

拦截器配置步骤
1、拦截器CommonSignParamsInterceptor类继承于okhttp3.Interceptor类,重写父类方法intercept
2、自定义一个private HashMap<String,String> getCommanParams()方法,在该方法当中,通过HashMap对象,以键值对方式设置公共参数
3、在intercept方法当中获取请求体,调用getCommanParams方法,重新配置请求体并发送请求

遇到的问题,当公共参数放在请求头header或者是form-body当中配置可能放便些,如下:

    @Override
    public Response intercept(@NonNull Chain chain) throws IOException {

        Response response;
        Request originRequest = chain.request();
        Request.Builder newRequest = originRequest.newBuilder();
        RequestBody body = originRequest.body();
        
        //添加请求头参数,调用addHeader(key,value)方法
        newRequest.addHeader("header-key",
               new JSONObject(getCommonParams()).toString());

        if (body == null) {
            body = EMPTY_BODY;
            newRequest.post(body);
        } else if(body instanceof FormBody){
            //添加表单参数form-body
            FormBody oldBody = (FormBody) body;
            FormBody.Builder newFormBodyBuilder = new FormBody.Builder();
            for (int i = 0; i < oldBody.size(); i++) {
                newFormBodyBuilder.add(oldBody.name(i), oldBody.value(i));
            }
            //添加公共参数
            for (Map.Entry<String, String> entry : getCommonParams().entrySet()) {
                newFormBodyBuilder.add(entry.getKey(), entry.getValue());
            }
            FormBody newFormBody = newFormBodyBuilder.build();
            newRequest.post(newFormBody);
        }
        response = chain.proceed(newRequest.build());

        return response;
    }

通过以上代码发现,添加请求头作为公共参数最简单,直接调用newRequest.addHeader就行,而添加表单参数也不难,只是简单的将原请求参数取出放入新的FormBody.Builder对象即可;那么还有一种情况,就是本文主题,如何将公共参数放入请求体body的json对象当中?

通过阅读源码,okhttp3.logging.HttpLoggingInterceptor发现,该拦截器是这样打印请求内容的,包括header等等请求信息:

      if (!logBody || !hasRequestBody) {
        logger.log("--> END " + request.method());
      } else if (bodyHasUnknownEncoding(request.headers())) {
        logger.log("--> END " + request.method() + " (encoded body omitted)");
      } else {
        Buffer buffer = new Buffer();
        requestBody.writeTo(buffer);

        Charset charset = UTF8;
        MediaType contentType = requestBody.contentType();
        if (contentType != null) {
          charset = contentType.charset(UTF8);
        }

        logger.log("");
        if (isPlaintext(buffer)) {
          logger.log(buffer.readString(charset));
          logger.log("--> END " + request.method()
              + " (" + requestBody.contentLength() + "-byte body)");
        } else {
          logger.log("--> END " + request.method() + " (binary "
              + requestBody.contentLength() + "-byte body omitted)");
        }
      }

通过以上源码可发现,else里面,将requestBody通过writeTo方法写入到buffer当中,再buffer内容读出,这就可先将原请求体和内容取出,取出之后,才能修改并加公共参数;具体实现代码跟源码方式大同小异,代码如下:

    @Override
    public Response intercept(@NonNull Chain chain) throws IOException {

        Response response;
        Request originRequest = chain.request();
        Request.Builder newRequest = originRequest.newBuilder();
        RequestBody body = originRequest.body();
        
        //添加请求头参数,调用addHeader(key,value)方法
        //newRequest.addHeader("header-key",
        //       new JSONObject(getCommonParams()).toString());

        if (body == null) {
            //------------
        } else if(body instanceof FormBody){
            //添加表单参数form-body
        } else if(body instanceof MultipartBody){
            //..........非本文主题
        } else {
            Buffer buffer = new Buffer();
            body.writeTo(buffer);
            Charset charset = Charset.forName("UTF-8");
            MediaType contentType = body.contentType();
            if (contentType != null) {
               charset = contentType.charset(charset);
               if (charset != null) {
               //读取原请求参数内容
               String requestParams = buffer.readString(charset);
               try {
                   //重新拼凑请求体
                   JSONObject jsonObject = new JSONObject(requestParams);
                   for (Map.Entry<String, String> entry : getCommonParams().entrySet()) {
                       jsonObject.put(entry.getKey(), entry.getValue());
                   }
                   RequestBody newBody = RequestBody.create(body.contentType(), jsonObject.toString());
                   newRequest.post(newBody);
                   } catch (JSONException e) {
                       e.printStackTrace();
                   }
               }
             }
        }
        response = chain.proceed(newRequest.build());

        return response;
    }

文毕,好好学习,天天向上 

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TenTenXu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值