zoukankan      html  css  js  c++  java
  • okhttp踩坑

    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);
    
  • 相关阅读:
    ubuntu环境下快速搭建开发环境
    Ubuntu安装mysql及设置远程访问方法
    lua 获取指定目录下指定后缀文件名
    DLL远程注入及卸载实现
    c字符检测函数
    数据库bcp导入导出批处理工具
    Schtasks命令详解(计划任务DOS批处理)
    lmathlib文件
    Github常用命令【转】
    Github上传代码菜鸟超详细教程【转】
  • 原文地址:https://www.cnblogs.com/xuanhaoo/p/14356305.html
Copyright © 2011-2022 走看看