前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >拒绝解析又臭又长的JSON

拒绝解析又臭又长的JSON

作者头像
疯狂的KK
发布2020-06-02 17:22:57
9600
发布2020-06-02 17:22:57
举报
文章被收录于专栏:Java项目实战Java项目实战

在日常工作中,不管是因为接收前端返回约定格式的JSON字符串,还是因为需要约定格式请求第三方服务,或者需要将前端画像xml解析成JSON,再或者需要接入第三方短信,供应商,数据提供商的JSON数据,或是需要提供对外暴露接口的API,可见解析JSON是一个常见操作。

JSON是一个轻量级的数据交换格式。

一:表单数据由数据库实体对象接收

常见的前后端约定字段,指定字段名称后,由数据库实体接收序列化后的表单数据,无序解析。

二:JSONObject解析

前后端约定格式,实体接收String类型,通过JSONObject解析JSON,JSONArray等操作

例如:

代码语言:javascript
复制
[
    {
        "children": [
            
        ],
        "createBy": "admin",
        "createTime": 1521171180000,
        "icon": "fa fa-gear",
        "menuId": 1,
        "menuName": "系统管理",
        "menuType": "M",
        "orderNum": "1",
        "params": {
            
        },
        "parentId": 0,
        "perms": "",
        "target": "",
        "url": "#",
        "visible": "0"
    },
    {
        "children": [
            
        ],
        "createBy": "admin",
        "createTime": 1521171180000,
        "icon": "fa fa-video-camera",
        "menuId": 2,
        "menuName": "系统监控",
        "menuType": "M",
        "orderNum": "2",
        "params": {
            
        },
        "parentId": 0,
        "perms": "",
        "target": "",
        "url": "#",
        "visible": "0"
    },
    {
        "children": [
            
        ],
        "createBy": "admin",
        "createTime": 1521171180000,
        "icon": "fa fa-bars",
        "menuId": 3,
        "menuName": "系统工具",
        "menuType": "M",
        "orderNum": "3",
        "params": {
            
        },
        "parentId": 0,
        "perms": "",
        "target": "",
        "url": "#",
        "visible": "0"
    },
    {
        "children": [
            
        ],
        "createBy": "admin",
        "createTime": 1590568770000,
        "icon": "fa fa-hand-peace-o",
        "menuId": 1062,
        "menuName": "我的朋友",
        "menuType": "C",
        "orderNum": "1",
        "params": {
            
        },
        "parentId": 1,
        "perms": "system:friends:view",
        "target": "menuItem",
        "url": "/system/friends",
        "visible": "0"
    },
    {
        "children": [
            
        ],
        "createBy": "admin",
        "createTime": 1521171180000,
        "icon": "#",
        "menuId": 100,
        "menuName": "用户管理",
        "menuType": "C",
        "orderNum": "1",
        "params": {
            
        },
        "parentId": 1,
        "perms": "system:user:view",
        "target": "",
        "url": "/system/user",
        "visible": "0"
    },
    {
        "children": [
            
        ],
        "createBy": "admin",
        "createTime": 1521171180000,
        "icon": "#",
        "menuId": 101,
        "menuName": "角色管理",
        "menuType": "C",
        "orderNum": "2",
        "params": {
            
        },
        "parentId": 1,
        "perms": "system:role:view",
        "target": "",
        "url": "/system/role",
        "visible": "0"
    },
    {
        "children": [
            
        ],
        "createBy": "admin",
        "createTime": 1521171180000,
        "icon": "#",
        "menuId": 102,
        "menuName": "菜单管理",
        "menuType": "C",
        "orderNum": "3",
        "params": {
            
        },
        "parentId": 1,
        "perms": "system:menu:view",
        "target": "",
        "url": "/system/menu",
        "visible": "0"
    }
]
通过JSONObject以及解析JSONArray获取

三:接入第三方API

接入第三方API,或者按约定调用第三方服务时,你会发现约定了又臭有长的JSON格式,包含特定字段,包含token,包含秘钥,一个详细数据解析接口,上百个字段是常见的,而且多种格式嵌套解析,如果单纯将收到的字符串手动转化成JSONObject,还要判空,还要层层遍历,还要验证数据的有效性,这是在是不小的工作量。

改造方法:提取最长,覆盖字段最全的作为实体列接收,含有List数据就由List接收,最外层K值由字段接收,涉及类型判断需按约定传不同数值的,定义为枚举,秘钥等特殊Key值MD5加解密传递。

代码语言:javascript
复制
// 如果url是空,则认为是解析历史数据 不需要拼装请求
        if (url != null && !"".equals(url)) {
            Client client = new Client();
            Map<String, String> params = new HashMap<String, String>();
            if ("mobileReli".equals(interfaceCode)) { //if类型判断定义为枚举      
                String infoJson = String.format("{\"phone\":\"%s\",\"name\":\"%s\",\"curDate\":\"%s\"}",
                        applyRecord.getPhone(), applyRecord.getName(), applyRecord.getFlashblackDate());
                StringBuffer sb = new StringBuffer();
                long time = System.currentTimeMillis();//重复度高的字段由优特实体类接收
                sb.append(secret + "!" + appKey + "!" + time + "!" + applyRecord.getName() + "!"
                        + applyRecord.getPhone() + "!" + secret + "!");
                sign = hdsClient.md5(sb.toString());
                String param = String.format("appKey=%s&infoJson=%s&sign=%s&time=%s", appKey, infoJson, sign, time);
                try {
                    jsonData = hdsClient.getResult(url, param);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            } else if ("DSModel".equals(interfaceCode)) {
                String infoJson = String.format("{\"mobile\":\"%s\",\"name\":\"%s\",\"starttime\":\"%s\"}",
                        applyRecord.getPhone(), applyRecord.getName(), applyRecord.getFlashblackDate());
                StringBuffer sb = new StringBuffer();
                long time = System.currentTimeMillis();
                sb.append(secret + "!" + appKey + "!" + time + "!" + applyRecord.getName() + "!"
                        + applyRecord.getPhone() + "!" + applyRecord.getFlashblackDate() + "!" + secret + "!");
                sign = hdsClient.md5(sb.toString());
                String param = String.format("appKey=%s&infoJson=%s&sign=%s&time=%s", appKey, infoJson, sign, time);
                try {
                    jsonData = hdsClient.getResult(url, param);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            } else if ("addressDetection".equals(interfaceCode)) {   
                String infoJson = String.format("{\"phone\":\"%s\",\"address\":\"%s\",\"curDate\":\"%s\"}",
                        applyRecord.getPhone(), applyRecord.getAddress(), applyRecord.getFlashblackDate());
                StringBuffer sb = new StringBuffer();
                long time = System.currentTimeMillis();
                sb.append(secret + "!" + appKey + "!" + time + "!" + applyRecord.getPhone() + "!"
                        + applyRecord.getAddress() + "!" + applyRecord.getFlashblackDate() + "!" + secret + "!");
                sign = hdsClient.md5(sb.toString());
                String param = String.format("appKey=%s&infoJson=%s&sign=%s&time=%s", appKey, infoJson, sign, time);
                try {
                    jsonData = hdsClient.getResult(url, param);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
public enum InterfaceCodeEnum {




    
    InterfaceCode1(1,"mobileReli"),
    InterfaceCode2(2,"DSModel"),
    InterfaceCode3(3,"addressDetection"),
    .
    .
    .
    ;


    private Integer code;
    private String name;


    InterfaceCodeEnum(Integer code, String name) {
        this.code = code;
        this.name = name;
    }


    public static String getNameBycode(Integer code) {
        if (code == null) {
            return "";
        }


        for (InterfaceCodeEnum a : InterfaceCodeEnum.values()) {
            if (a.code.equals(code)) {
                return a.name;
            }
        }


        return "";
    }
}


@Builder
@Data
public class InterfaceCodeResult implements Serializable {


    //基础信息
    private Base base;
    //秘钥信息
    private AuthInfo authInfo;
    //外层字段封装为对象接收
    private AddressResult  addressResult;
    //重复多层信息List接收
    private List<Flashblack> flashblack;
}

当接收到JSON字符串时

代码语言:javascript
复制
InterfaceCodeResult codeResult=JSONObject.parseObject(InterfaceCodeResult.getRequestInfo(),InterfaceCodeResult.class);
if(PreInterfaceStatus.equals(codeResult.base.getTyep())){
  return JavaConvertUtil.conversion(codeResult, CodeParams.class);
}

仅需要判断多个类型即可,对应字段会自动解析,当接收又臭又长的XML解析还需要后端验证时,需要封装Util类进行验证调用

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 赵KK日常技术记录 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档