json对象互转问题记录

Posted 波子汽水yeah

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了json对象互转问题记录相关的知识,希望对你有一定的参考价值。

遇到一个神奇的问题

在项目里面前端接收的一个string类型的json转换成对象的时候报错

cn.hutool.core.convert.ConvertException: No Converter for type [java.util.List]

然后不服气的我拿出来研究了一下,结果发现在新建的工程里面没有问题。这就很尴尬了。本着不不服气的精神,又研究了好久,把实体类拷出来一模一样还是报错。既然实体都一样了。猛然想起。两个工程用的hutool包版本不一致。最后把测试工程的hutool包降级版本后问题就重现。项目里hutool包 4.5.11测试工程里面5.3.10版本

记录一下,踩了这个坑

   
        String txt ="\\"logType\\":4,\\"beInviterPrizePoolId\\":1298,\\"updateCode\\":\\"191095846\\",\\"theMax4ShareReward\\":\\"完成本阶梯任务数量\\",\\"inviteRules\\":[\\"helpTarget\\":[\\"eventType\\":\\"member\\",\\"event\\":154,\\"eventBody\\":[\\"branch_name\\":\\"分支名称\\",\\"event\\":[\\"column_name\\":\\"register_area\\",\\"column_value\\":\\"110101\\",\\"meta_column_id\\":2175,\\"column_value_type\\":\\"field\\",\\"web_value\\":\\"\\\\\\"province\\\\\\":[\\\\\\"11\\\\\\"],\\\\\\"city\\\\\\":[\\\\\\"1101\\\\\\"],\\\\\\"region\\\\\\":[\\\\\\"110101\\\\\\"]\\",\\"column_name\\":\\"register_store_manager_code\\",\\"column_value\\":\\"C-P101-A155-M0374-B1855-DDTT01\\",\\"meta_column_id\\":2176,\\"column_value_type\\":\\"field\\",\\"column_value_ext\\":\\"table_name\\":\\"cdp_store_imp\\",\\"column_name_select\\":\\"org_code_long\\",\\"column_name_where\\":[\\"batch_no\\",\\"brand_code\\"],\\"where_value\\":[\\"\\",\\"TS\\"],\\"web_value\\":\\"\\\\\\"bigAreas\\\\\\":\\\\\\"C\\\\\\",\\\\\\"smallAreas\\\\\\":\\\\\\"C-P101\\\\\\",\\\\\\"managerAreas\\\\\\":\\\\\\"C-P101-A155\\\\\\",\\\\\\"managerCityAreas\\\\\\":\\\\\\"C-P101-A155-M0374\\\\\\",\\\\\\"operateCities\\\\\\":\\\\\\"\\\\\\",\\\\\\"storeItems\\\\\\":\\\\\\"C-P101-A155-M0374-B1855-DDTT01\\\\\\",\\\\\\"selectedStoreItems\\\\\\":[\\\\\\"orgCode\\\\\\":\\\\\\"DDTT01\\\\\\",\\\\\\"orgName\\\\\\":\\\\\\"DDTT01-1\\\\\\",\\\\\\"orgCodeLong\\\\\\":\\\\\\"C-P101-A155-M0374-B1855-DDTT01\\\\\\"]\\",\\"column_name\\":\\"register_time\\",\\"column_value\\":\\"@2021-08-26 00:00:00,2021-08-27 23:59:59\\",\\"meta_column_id\\":2177,\\"column_value_type\\":\\"field\\",\\"column_name\\":\\"register_source\\",\\"column_value\\":\\"offline\\",\\"meta_column_id\\":2178,\\"column_value_type\\":\\"enum2Filter\\",\\"column_value_ext\\":\\"offline\\":[\\"03\\",\\"11\\",\\"19\\",\\"48\\",\\"27\\",\\"31\\",\\"09\\",\\"07\\"]]],\\"helpTargetName\\":\\"助力任务描述\\"],\\"countWithInviter\\":true,\\"finishThisLadderNum\\":\\"完成本阶梯任务数量\\",\\"thisLadderPrizePoolId\\":1298,\\"ladderImg\\":\\"https://crm-resource-test.topsports.com.cn/group1/M00/08/32/Cgn72WEKSCeAWLyyAAABS4B__A8285.png\\",\\"sendTimeType\\":0,\\"sendTimeVal\\":\\"\\"],\\"actModel\\":3,\\"updateUser\\":\\"闫凯梦\\",\\"inviteType\\":3,\\"freezeTime\\":\\"2021-08-18 00:00:00\\",\\"beInviterCanGetMaxLimit\\":\\"可获得奖励次数\\",\\"activityId\\":\\"26ccc8b7c23b42669c0f795d2e4e070c\\",\\"sharePrizePoolId\\":1298,\\"logOperationType\\":1";

 ActRuleConfigDto actRuleConfigDto =  JSONUtil.toBean(txt, ActRuleConfigDto.class);
        System.out.println("======"+JSONUtil.toJsonStr(actRuleConfigDto));

查明原因,因为实体里面定义的字段theMax4ShareReward是int类型传入的是string 报了这个错。被这个报错【No Converter for type [java.util.List]】误导了。

测试工程里面 JSON.toJsonString(actRuleConfigDto) 报错了

java.lang.ClassCastException: cn.hutool.core.bean.PropDesc cannot be cast to cn.hutool.core.bean.BeanDesc$PropDesc
奇怪的时,当我搞明白版本这个问题居然不报错了 猜测还是包版本的问题。

另外推荐一个好用的json解析工具


        <dependency>
            <groupId>org.noear</groupId>
            <artifactId>snack3</artifactId>
            <version>3.1.18</version>
            <scope>provided</scope>
        </dependency>



        String jsonStr ="\\"code\\":1,\\"data\\":\\"claimNum\\":1,\\"couponCodes\\":[\\"这是一个测试券号忽略\\"],\\"couponList\\":[\\"couponCode\\":\\"这是一个测试券号忽略\\",\\"endTime\\":\\"2021-08-31 23:59:59\\",\\"startTime\\":\\"2021-08-05 00:00:00\\",\\"ticketPassword\\":\\"\\",\\"ticketUrl\\":\\"\\"],\\"couponRuleCode\\":\\"HTDT21029679\\",\\"couponRuleName\\":\\"xxx九折优惠券051\\",\\"couponType\\":1,\\"couponTypeSub\\":11,\\"discType\\":1,\\"faceMoney\\":10,\\"message\\":\\"领取成功\\",\\"showFinishFlag\\":0,\\"vipFlag\\":false,\\"bizMsg\\":\\"成功\\",\\"bizCode\\":20000";
        ONode o = ONode.load(jsonStr);
        o.set("bizCode",2);
        System.out.println(o.select("$.bizCode"));
        ONode data = o.select("$.data");
        JSONObject couponInfo = new JSONObject();
        couponInfo.put("couponRuleName",data.select("$.couponRuleName").getString());
        couponInfo.put("couponMoneyType",data.select("$.discType").getString());
        couponInfo.put("couponMoney",data.select("$.faceMoney").getString());
        couponInfo.put("isretail",data.select("$.couponType").getInt());
        couponInfo.put("startTime",data.select("$.couponList[0].startTime").getString());
        couponInfo.put("endTime",data.select("$.couponList[0].endTime").getString());
        couponInfo.put("showFinishFlag",data.select("$.showFinishFlag").getInt());
        couponInfo.put("couponCode",data.select("$.couponList[0].couponCode").getString());
        System.out.println(JSON.toJSONString(couponInfo));

        System.out.println(o.get("data").get("couponList").get(0).get("couponCode"));


// string转对象

        ActRuleConfigDto  actRuleConfigDto2 = ONode.deserialize(txt,ActRuleConfigDto.class);
        System.out.println("字符串化:"+ONode.stringify(actRuleConfigDto2));
        System.out.println("序列化="+ONode.serialize(actRuleConfigDto2));


上面类型不对的json用ONode 转对象的时候会报错

java.lang.RuntimeException: java.lang.NumberFormatException: For input string: "完成本阶梯任务数量"
这个就比hutool的报错友好很多!

简单的性能对比

 @Test
    public void tests()
        String txt ="\\"logType\\":4,\\"beInviterPrizePoolId\\":1298,\\"updateCode\\":\\"191095846\\",\\"theMax4ShareReward\\":3,\\"inviteRules\\":[\\"helpTarget\\":[\\"eventType\\":\\"member\\",\\"event\\":154,\\"eventBody\\":[\\"branch_name\\":\\"分支名称\\",\\"event\\":[\\"column_name\\":\\"register_area\\",\\"column_value\\":\\"110101\\",\\"meta_column_id\\":2175,\\"column_value_type\\":\\"field\\",\\"web_value\\":\\"\\\\\\"province\\\\\\":[\\\\\\"11\\\\\\"],\\\\\\"city\\\\\\":[\\\\\\"1101\\\\\\"],\\\\\\"region\\\\\\":[\\\\\\"110101\\\\\\"]\\",\\"column_name\\":\\"register_store_manager_code\\",\\"column_value\\":\\"C-P101-A155-M0374-B1855-DDTT01\\",\\"meta_column_id\\":2176,\\"column_value_type\\":\\"field\\",\\"column_value_ext\\":\\"table_name\\":\\"cdp_store_imp\\",\\"column_name_select\\":\\"org_code_long\\",\\"column_name_where\\":[\\"batch_no\\",\\"brand_code\\"],\\"where_value\\":[\\"\\",\\"TS\\"],\\"web_value\\":\\"\\\\\\"bigAreas\\\\\\":\\\\\\"C\\\\\\",\\\\\\"smallAreas\\\\\\":\\\\\\"C-P101\\\\\\",\\\\\\"managerAreas\\\\\\":\\\\\\"C-P101-A155\\\\\\",\\\\\\"managerCityAreas\\\\\\":\\\\\\"C-P101-A155-M0374\\\\\\",\\\\\\"operateCities\\\\\\":\\\\\\"\\\\\\",\\\\\\"storeItems\\\\\\":\\\\\\"C-P101-A155-M0374-B1855-DDTT01\\\\\\",\\\\\\"selectedStoreItems\\\\\\":[\\\\\\"orgCode\\\\\\":\\\\\\"DDTT01\\\\\\",\\\\\\"orgName\\\\\\":\\\\\\"DDTT01-1\\\\\\",\\\\\\"orgCodeLong\\\\\\":\\\\\\"C-P101-A155-M0374-B1855-DDTT01\\\\\\"]\\",\\"column_name\\":\\"register_time\\",\\"column_value\\":\\"@2021-08-26 00:00:00,2021-08-27 23:59:59\\",\\"meta_column_id\\":2177,\\"column_value_type\\":\\"field\\",\\"column_name\\":\\"register_source\\",\\"column_value\\":\\"offline\\",\\"meta_column_id\\":2178,\\"column_value_type\\":\\"enum2Filter\\",\\"column_value_ext\\":\\"offline\\":[\\"03\\",\\"11\\",\\"19\\",\\"48\\",\\"27\\",\\"31\\",\\"09\\",\\"07\\"]]],\\"helpTargetName\\":\\"助力任务描述\\"],\\"countWithInviter\\":true,\\"finishThisLadderNum\\":4,\\"thisLadderPrizePoolId\\":1298,\\"ladderImg\\":\\"https://crm-resource-test.topsports.com.cn/group1/M00/08/32/Cgn72WEKSCeAWLyyAAABS4B__A8285.png\\",\\"sendTimeType\\":0,\\"sendTimeVal\\":\\"\\"],\\"actModel\\":3,\\"updateUser\\":\\"闫凯梦\\",\\"inviteType\\":3,\\"freezeTime\\":\\"2021-08-18 00:00:00\\",\\"beInviterCanGetMaxLimit\\":9,\\"activityId\\":\\"26ccc8b7c23b42669c0f795d2e4e070c\\",\\"sharePrizePoolId\\":1298,\\"logOperationType\\":1";
        long start  = System.currentTimeMillis();
        for (int i =0;i<100000;i++)
            ActRuleConfigDto  actRuleConfigDto2 = ONode.deserialize(txt,ActRuleConfigDto.class);
//           String res =ONode.stringify(actRuleConfigDto2);
        
        long end = System.currentTimeMillis();
        System.out.println("ONode序列化耗时1="+(end-start));

        long start2  = System.currentTimeMillis();
        for (int i =0;i<100000;i++)
            ActRuleConfigDto actRuleConfigDto =  JSONUtil.toBean(txt, ActRuleConfigDto.class);
//           String res =com.alibaba.fastjson.JSONObject.toJSONString(actRuleConfigDto);
        
        long end2 = System.currentTimeMillis();
        System.out.println("ONode序列化耗时2="+(end2-start2));
//        ONode序列化耗时1=1073
//        ONode序列化耗时2=1497

        //去掉反序列化 仅 str转对象  性能好了快一倍
//        ONode序列化耗时1=699
//        ONode序列化耗时2=1339

    

ONode性能好了快一倍。但是对象转str的时候hutool的更快 

以上是关于json对象互转问题记录的主要内容,如果未能解决你的问题,请参考以下文章

json对象互转问题记录

XML对象与json对象互转

javascript中json对象json数组json字符串互转及取值

JS json对象(Object)和字符串(String)互转方法

OkHttp发起网络请求以及JSON/XML与对象的互转

json串与java对象互转