ResponseBody.string()

   平常我们用的客户端http调用工具一般是RestTemplate,HttpClient,okhttp,以前使用过前两者,没咋接触过okhttp,我看公司项目中使用okhttp比较多,于是我这次也用了一下okhttp,果不其然,还是自己踩了一个坑:

   下面是一个okhttp请求的代码块:

...
okhttp3.Request okHttpRequest = new okhttp3.Request.Builder()
.url(saveUrl)
.post(requestBody)
.build();
Call call = okHttpClient.newCall(okHttpRequest);
try {
okhttp3.Response response = call.execute();
if (Objects.nonNull(response)) {
ResponseBody responseBody = response.body();
if (Objects.nonNull(responseBody)) {
log.info("responseBody:{}", responseBody.string());
String responseBodyString = responseBody.string();
Response resultTmp = JSON.parseObject(responseBodyString, Response.class);
if (resultTmp.getCode() == ResponseCodeEnum.COMPANY_NOT_EXSIT.getCode()) {
throw new GlobalException(ResponseCodeEnum.COMPANY_NOT_EXSIT);
}
}
} else {
log.info("erp-service saveQuesFeedback-请求没有返回数据");
}
} catch (IOException e) {
log.error("erp-service-forward saveQuesFeedback-Exception", e);
throw new GlobalException(ResponseCodeEnum.FAIL);
}
...

   一般在请求http的时候,习惯先打印返回的数据,然后再取值。在调试的时候,每次请求都是返回的成功结果,但是走到后边的code判断逻辑就开始报异常,responseBody:{}都是打印的正常结果,那问题在哪呢,刚开始调试粒度太宽,后边一行一行的来进行调试,发现走到第13行,取到结果是空的,说明responseBody.string()没有获取到,但是日志里面明明打印的有,结果查看了一下源代码:

public abstract class ResponseBody implements Closeable {
@Nullable
private Reader reader; public ResponseBody() {
} public final String string() throws IOException {
BufferedSource source = this.source();
Throwable var2 = null; String var4;
try {
Charset charset = Util.bomAwareCharset(source, this.charset());
var4 = source.readString(charset);
} catch (Throwable var8) {
var2 = var8;
throw var8;
} finally {
if (source != null) {
$closeResource(var2, source);
} } return var4;
}
}

   ResponseBody实现了Closeable,然后获取body的内容,finally中closeResource,原来在获取string后会关闭数据流,

所以在第二次就获取不到数据了。

所以在使用response.string()的时候要先取出返回的数据,然后再打印结果:

// 此处responseBody.string 只能获取一次就会关闭,所以要先赋值
String responseBodyString = responseBody.string();
log.info("responseBody:{}", responseBodyString);

okhttp踩坑的更多相关文章

  1. OkHttp踩坑记:为何 response.body().string() 只能调用一次?

    想必大家都用过或接触过 OkHttp,我最近在使用 Okhttp 时,就踩到一个坑,在这儿分享出来,以后大家遇到类似问题时就可以绕过去. 只是解决问题是不够的,本文将 侧重从源码角度分析下问题的根本, ...

  2. Spark踩坑记——Spark Streaming+Kafka

    [TOC] 前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark strea ...

  3. Spark踩坑记——数据库(Hbase+Mysql)

    [TOC] 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库,去统计或者改变一些值.最近一个实时消费者处理任务,在使用spark streami ...

  4. 【踩坑速记】二次依赖?android studio编译运行各种踩坑解决方案,杜绝弯路,总有你想要的~

    这篇博客,只是把自己在开发中经常遇到的打包编译问题以及解决方案给大家稍微分享一下,不求吸睛,但求有用. 1.大家都知道我们常常会遇到dex超出方法数的问题,所以很多人都会采用android.suppo ...

  5. NPOI导出Excel (C#) 踩坑 之--The maximum column width for an individual cell is 255 charaters

    /******************************************************************* * 版权所有: * 类 名 称:ExcelHelper * 作 ...

  6. 我的微信小程序入门踩坑之旅

    前言 更好的阅读体验请:我的微信小程序入门踩坑之旅 小程序出来也有一段日子了,刚出来时也留意了一下.不过赶上生病,加上公司里也有别的事,主要是自己犯懒,就一直没做.这星期一,赶紧趁着这股热乎劲,也不是 ...

  7. router路由去掉#!的踩坑记

    项目中在研究去掉router#!的过程中的踩坑过程.

  8. vue+ vue-router + webpack 踩坑之旅

    说是踩坑之旅 其实是最近在思考一些问题 然后想实现方案的时候,就慢慢的查到这些方案   老司机可以忽略下面的内容了 1)起因  考虑到数据分离的问题  因为server是express搭的   自然少 ...

  9. 记jQuery.fn.show的一次踩坑和问题排查

    最近很少已经很少用jQuery,因为主攻移动端,常用Zepto,其实很多细节和jQuery并不一样.最近又无意中接触到了PC的需求和IE6, 使用了jQuery,刚好踩坑了,特意记录一下. 本文内容如 ...

随机推荐

  1. VS使用过程中可能会遇到的问题

    Q:某个类无法引用命名空间 A:可能是类名与文件夹名重复了

  2. logback日志对象要素

    <logger>节点 分两种 1.是普通日志对象 logger分为2种,一种是普通日志对象,另一种是根日志对象.对于大部分应用来说,只设置根日志对象即可. 在java日志系统中,无论是lo ...

  3. Mybatis利用Intercepter实现物理分页

    一.Interceptor介绍 Mybatis 允许用户使用自定义拦截器对SQL语句执行过程中的某一点进行拦截.默认情况,可以拦截的方法如下: Executor 中的 update().query() ...

  4. LeapMotion控制器 java语言开发笔记--(LeapMotion控制器简介)

    (1)LeapMotion系统识别和追踪手,手指,以及根手指类似的工具,这个设备运行在一个极小的范围,这个范围拥有个高精度,高跟踪频率可以记录离散的点,手势,和动作. (2)LeapMotion控制器 ...

  5. TCP超时重传时间的选择

    一---导读 TCP超时重传时间的选择是计算机网络中较复杂的问题之一,但幸好前辈们都把路铺好了,我们只需要学习并且遵循这些规则,有能力的话去进一步改正. 二---必知的一些专业术语 A--RTT( r ...

  6. .NET 云原生架构师训练营(模块二 基础巩固 MongoDB API实现)--学习笔记

    2.5.7 MongoDB -- API实现 问题查询单个实现 问题查询列表实现 问题跨集合查询实现 问题创建实现 问题更新实现 问题回答实现 问题评论实现 问题投票实现 回答实现 QuestionC ...

  7. Redis学习之路(三)常用命令总结

    一.集群 查看Redis集群有多少个库 192.168.200.100:7001> config get databases 1) "databases" 2) " ...

  8. Ubuntu/Liinux睡眠无法唤醒解决方法:ACPI设置

    最近给笔记本换了一个固态,顺便就重装了一下系统,版本是Ubuntu 20.10.装完之后各种功能基本都是正常的,触摸板轻触单击.双指右键等功能开箱即用.但是在安装完最新的Nvidia驱动之后就出现了问 ...

  9. 双重校验锁 --使用volatile和两次判空校验

    介绍 双重校验锁是单例模式中,饿汉式的一种实现方式.因为有两次判空校验,所以叫双重校验锁,一次是在同步代码块外,一次是在同步代码块内. 为什么在同步代码块内还要再检验一次? 第一个if减少性能开销,第 ...

  10. 【剑指 Offer】10-I.斐波那契数列

    题目描述 写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项.斐波那契数列的定义如下: F(0) = 0,   F(1) = 1 F(N) = F(N - 1) + F(N - ...