OkHttp3请求中readTree报'Unrecognized token okhttp3'的排查与解决
问题分析与解决方案
核心错误原因
你代码里的response.body().toString()并未获取到真实的响应内容,而是调用了ResponseBody对象的默认toString()方法,返回的是对象的类名加内存哈希值(也就是报错里的okhttp3.internal.http.RealResponseBody@3bb3d2d4)。ObjectMapper把这个非JSON格式的字符串当成JSON解析,必然抛出格式错误。
修复代码
将获取响应内容的方式替换为response.body().string(),这个方法会读取响应体的真实字符串内容(注意:该方法只能调用一次,因为ResponseBody的流会被读取后关闭)。修改后的关键代码片段:
try (Response response = call.execute()) { // 替换toString()为string()获取真实响应JSON String json = response.body().string(); JsonNode node = objectMapper.readTree(json); // 后续节点遍历逻辑保持不变 if(node.has("foo") && node.get("foo").has("boo")) { node = node.get("foo").get("boo"); for(int i = 0; i < node.size(); i++) { result.add(this.parseJson(node.get(i))); } // ... 其他逻辑 } return Optional.empty(); } catch (IOException e) { log.error(e.getMessage()); }
响应排查方法
如果修复后仍有问题,或需要确认响应结构,可以通过以下方式排查:
- 打印响应日志:在获取
json字符串后,添加日志打印完整内容,确认是否为合法JSON:log.info("完整响应内容: {}", json); - 修复curl请求显示问题:如果curl请求看不到可读内容,大概率是响应启用了压缩(如gzip),需要添加参数解压:
curl -H "Accept-Encoding: gzip, deflate" --compressed 你的请求URL - 添加OkHttp调试拦截器:通过拦截器打印完整的请求/响应详情,且不影响后续业务逻辑:
OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); log.info("请求URL: {}", request.url()); log.info("请求头: {}", request.headers()); Response response = chain.proceed(request); log.info("响应状态码: {}", response.code()); log.info("响应头: {}", response.headers()); // 读取前1MB响应内容(避免大响应导致OOM) String debugBody = response.peekBody(1024 * 1024).string(); log.info("响应内容(前1MB): {}", debugBody); return response; } }) .build();
补充说明
你提到因响应包含保留字而选择readTree而非readValue的思路是合理的,只要获取到正确的JSON字符串,后续的节点遍历逻辑可以正常执行。
内容的提问来源于stack exchange,提问作者vic
相关产品推荐
相关产品推荐

