解析HTTP响应的-超大JSON内容

解析HTTP响应的-超大JSON内容

一、需求背景

最近在做系统对接时遇到个比较特殊的情况,简要任务就是通过第三方提供的接口去查询对应的图片数据;(在一般情况下可能说会是返回他们的一个图片地址,然后再由我们系统进行下载流进行上传;要么是返回图片的Base64字符),也许Base64的对接方式更常见。

当然,接到这个需求的接口也是通过Base64的方式传送数据。那。。。这不是一般的情况吗,应该没什么问题吧,接收返回的json,然后解析Base64字符串,最后转为图片,不就完事了吗?

嗯。。。。你是对的,当时我拿到需求时也是这么想。但是当我部署上去测试时: OOM
在这里插入图片描述

二、天真的BB

当时按着接口文档一顿乱敲(接口文档提供了响应json的简单结构)

 //请求
 HttpResponse response = HttpRequest.post("")
                .header(headerMap)
                .body(map).execute();
//获取响应内容(json字符串)
JSONObject jsonObject = JSON.parseObject(response.body());
//解析Base64 ....

以上就是看似简单无误的逻辑,但如果你知道请求返回的巨物后就会沉思了,毕竟知道一张图片转换成base64字符串可能就几M(百万+个字符)。

如果是一个请求返回五六张图就算了,当我看到生产环境返回的数据,竟然200M+ (这里通过读取response.bodyStream()将它写到本地文件时的文件大小)。

反正我是emo了,就问你emo不emo吧。

这里主要溢出的是在response.body(),而response.body()内部其实就是一个new String();也就是说把整个响应字符串放进一个String类型中。所以我们需要做的就是跳过 这一步骤(放进String的这一操作)

三、方案一:先保存到本地文件,再使用工具解析

既然刚才已经把响应Json保存到本地了,那就顺势而为:

		String filPath= "/xxx.txt";
 		InputStream in = response.bodyStream();
        byte[] bytes = new byte[1024];
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(filPath);
            int b;
            while ((b = in.read(bytes)) != -1) {
                fos.write(bytes, 0, b);
            }
            fos.close();
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

再通过工具读取文件进行解析json,如JsonFactory类(com.fasterxml.jackson)

		File file = new File(filePath);
        JsonFactory f = new MappingJsonFactory();
        JsonParser jp = f.createJsonParser(file);
        JsonToken current;
        current = jp.nextToken();
       
       if (current == JsonToken.START_OBJECT) {
         while (jp.nextToken() != JsonToken.END_OBJECT) {
            String fieldName = jp.getCurrentName();
            current = jp.nextToken();
            if (fieldName.equals("data")) {
                if (current == JsonToken.START_ARRAY) {
                    while (jp.nextToken() != JsonToken.END_ARRAY) {
                        JsonNode node = jp.readValueAsTree();
                        //获取树节点数据
                        node.get("");
                        }
                  }else{
                    //跳过不符合的值
                  	jp.skipChildren();
				  }
             }else{
             	 //跳过不符合的值
                 jp.skipChildren();
			 }
          }
        }

JsonToken类定义了Json格式的各种标识
在这里插入图片描述
最后就是解读图片上传到文件服务器,与相关业务进行关联。

取完我们所需的数据后,记得进行删除本地文件,除非有保留的必要

//删除文件
file.delete();

也许还有其他的工具可以更简单的解析实现,后续待更。。。。。

其实最佳的应该是直接解析数据流response.bodyStream();从流中解析出所需要的数据(Base64),小弟学识尚浅,若有大神已实现,望不吝赐教

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值