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

2023-11-02

当网络请求都是基于一个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;
    }

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • Apache下设置整站变灰方法

    本文转载自http www sapub net Apache 感谢作者分享 Web服务器下设置变灰的方法比较简单 总结如下 1 安装mod ext filter模块 此模块用来在所有的输出页面插入你想要的内容 比如css 广告头之类 这里假
  • centos7设置静态IP地址

    有时候我们电脑 老是换网线 这个时候虚拟机ip就会跟着变 所以这里我建议大家直接配置静态ip 这样可以避免ip变化 目录 1 查看IP配置信息 从中获取网卡名称 2 编辑网卡名称对应的配置文件 3 修改 etc sysconfig netw
  • QT父窗口和子窗口互相通信

    这个问题上网查了好多 大神们都说的很简单 对于我这样的小白来说 理解起来就有点吃力了 下面记录一下 给自己留给笔记 也是给正在摸索中的小白们一点参考 一 大家要明白如何建立子窗口 1 利用新建ui的方式来新建 我没有用这种方式 这里就先不说
  • php 命令执行中 PHPSESSID 妙用

    php 命令执行中 PHPSESSID 妙用 前言 题目地址 查看源码 使用PHPSESSID绕过限制 使用反引号绕过限制 前言 之前刷CTF的时候 遇到一个命令执行的题 看大佬的WP是通过PHPSESSID传值 绕过waf 最近有时间复现
  • Python时间格式转换

    一 标准库 1 import time time模块中时间表现的格式主要有三种 a timestamp时间戳 时间戳表示的是从1970年1月1日00 00 00开始按秒计算的偏移量 b struct time时间元组 共有九个元素组 c f
  • 【解答】CSDN的c认证有含金量么?

    我就从考试难度 报名费用 企业认可度这几个点介绍一下吧 一 考试难度 C认证分 c1 c4 c5 三个等级 c1认证 是最基础的入门考试 以前端知识居多 考试内容多以 块状元素有哪些 行级元素有哪些居多 考试最后大题是用 html css
  • property_exists 检查对象或类是否具有该属性

    bool property exists mixed class string property 1 class myClass public mine private xpto static protected test static f
  • 有一行字符,统计其中的单词个数(单词之间以空格分隔),并将每一个单词的第一个字母改为大写。

    每天自己做的作业 不喜勿喷 define CRT SECURE NO WARNINGS include stdio h include stdlib h include string h int myStr char p int n int

随机推荐

  • Android:Namespace not specified. Please specify a namespace in the module‘s build.gradle file like

    文章目录 问题描述 解决方法 参考链接 问题描述 问题 接上文 解决方案记录 Could not find com android tools build gradle 8 0 在修改完对应的文件之后 并将compileSdk 版本号改为3
  • ./configure: error: C compiler cc is not found

    1 报错信息 configure error C compiler cc is not found 2 原因 没有下载gcc编译器 3 解决办法 用以下命令下载gcc编译器 yum y install gcc gcc c autoconf
  • 建立 PyQt6 窗口

    建立 PyQt6 窗口 这篇教学会介绍如何开始使用 PyQt6 建立基本的应用程序窗口 以及通过常用的窗口参数 进行窗口的相关设定 快速导航 建立 PyQt6 窗口 调整窗口样式 在窗口中放入其他组件 建立 PyQt6 窗口 PyQt6 创
  • ASP.NETCore WebApp + EFCore +Docker +MSSQL(Docker for Window)

    文章目录 一 本机环境 二 创建ASP NET Core WebApp 创建项目 添加模型 搭建基架 使用CoreFirst方式初始数据库架构 三 MSSQL Docker 拉取MSSQL Docker镜像 启动容器 环境要求 参数解析 连
  • socket failed: EPERM (Operation not permitted) 解决方法

    1 网络权限没有开启 2 不支持http 在AndroidManifest xml 中添加网络权限
  • 安全HCIP之IPX

    IPX Internetwork Packet Exchange protocol 互联网分组交换协议 IPX 是指互联网分组交换协议 提供分组寻址和选择路由的功能 保证可靠到达 相当于数据报的功能 SPX 是顺序报文分组交换协议 它可保证
  • C/C++ 代码编译过程【复习】

    C C 代码编译过程 很久很久没用过 C C 突然碰到编译过程 竟有些想不起来 这里复习一下 C 语言的编译链接过程要把我们编写的一个 C 程序 源代码 转换成可以在硬件上运行的程序 可执行代码 如汇编语言 机器语言 分两个部分 编译和链接
  • LLM系列

    简介 小伙伴们好 我是 小窗幽记机器学习 的小编 卖热干面的小女孩 紧接前文 万字长文细说ChatGPT的前世今生 后续会尝试以理论 实践的方式逐步对主流的各大LLM进行实测和汉化 今天这篇关于Llama2的小作文其实比较长 所以分为上下两
  • Python爬虫实战(3)-爬取豆瓣音乐Top250数据(超详细)

    前言 首先我们先来回忆一下上两篇爬虫实战文章 第一篇 讲到了requests和bs4和一些网页基本操作 Python爬虫实战 1 爬取 房天下 租房信息 超详细 第二篇 用到了正则表达式 re模块 Python爬虫实战 2 爬取小说 斗罗大
  • linux磁盘虚拟化

    1 LVM Logical Volume Manager 逻辑滚动条管理员 LVM可以将几个实体的partions 或disk 透过软件组合成为一块看起来是独立的大磁盘 VG 然后将这块大磁盘再经过分割成为可使用分隔槽 LV 最终就能够挂载
  • 【SQL注入-可回显】报错注入:简介、相关函数、利用方法

    目录 一 定义 1 1 简介 1 2 利用 1 3 利用过程 1 4示例 注 二 相关函数 2 1 最常用的三种是 2 2 Xpath语法错误 extractvalue updatexml 2 3 数据溢出 exp 2 4 主键重复 原理
  • php 大转盘抽奖概率 角度,在线抽奖大转盘和概率计算

    html gt 抽奖效果演示 rotary position relative width 854px height 504px margin 0 auto background d71f2e url p w picpaths bg1 pn
  • 3D游戏编程设计作业九

    P D 过河游戏智能帮助实现 程序具体要求 实现状态图的自动生成 讲解图数据在程序中的表示方法 利用算法实现下一步的计算 状态图分析 此次作业的代码基于第三次作业 牧师与魔鬼的动作分离版代码进行改进 加入了智能提示功能 实现效果图如下 要实
  • Android ImageView视图的七种图片缩放类型

    博主前些天发现了一个巨牛的人工智能学习网站 通俗易懂 风趣幽默 忍不住也分享一下给大家 点击跳转到网站 前言 ImageView默认图片居中显示 默认图片的缩放类型为 scaleType属性为 fitCenter 一 scaleType属性
  • 【严重】vm2 <3.9.18 沙箱逃逸漏洞(存在POC)

    漏洞描述 vm2 是一个基于 Node js 的沙箱环境 可以使用列入白名单的 Node 内置模块运行不受信任的代码 代理对象用于拦截并重定义宿主对象的各种操作 vm2 3 9 18之前版本中 由于 prepareStackTrace 函数
  • 【转】OSI TCP/IP 浅析

    OSI是Open System Interconnect的缩写 意为开放式系统互联 国际标准组织 国际标准化组织 制定了OSI模型 这个模型把网络通信的工作分为7层 分别是物理层 数据链路层 网络层 传输层 会话层 表示层 应用层 一 网络
  • unity控制物体显示和隐藏的方法总结

    首先是物体的获取 代码如下 GameObject Find SampleAnchorMe 找到并返回一个名字为SampleAnchorMe的游戏物体 不能用于inactive的物体即隐藏的物体无法用find发现 GameObject Fin
  • 4:eMMC command

    1 前言 本文主要对eMMC的command进行详细介绍 主要包含如下内容 1 command类型 2 command格式 2 command类型 command类型 说明 bc 不带response的广播命令 bcr 带有response
  • 华为机试C语言-最长方连续方波信号

    题目描述 https zhuanlan zhihu com p 546563566 代码分层有利于代码调试 include
  • Okhttp设置公共参数,以json对象放入@Body请求公共参数的配置方式

    当网络请求都是基于一个URL 所有的接口都是同一个地址 而请求不同接口数据则是通过command字段进行配置 然后所有的请求参数都是需要自己写一个bean类 再转成json格式放入请求body里发给后台 而不是通过表单form body发送