一、场景
1、将net.sf.json.JSONObject转为实体对象
2、实体对象包含List类型的属性
3、操作List属性时报错(本篇以遍历List时报错为例)
二、报错信息
java.lang.ClassCastException: net.sf.ezmorph.bean.MorphDynaBean cannot be cast to com.xxx.entity.serviceflow.BranchNodeCondition at com.xxx.util.ServiceFlowHandlerUtil.matchBranchHandle(ServiceFlowHandlerUtil.java:519) at org.apache.rocketmq.client.impl.consumer.ConsumeMessageConcurrentlyService$ConsumeRequest.run(ConsumeMessageConcurrentlyService.java:411) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)
三、代码
1、实体
package com.xxx.entity.serviceflow;import lombok.Data;import java.util.List;@Datapublic class BranchNodeData { private Long branchId; private Integer seq; private String branchType; private String branchMemo; private Long branchJumpId; //实体包含List类型的属性 private ListconditionList;}
2、测试
package com.xxx;import com.xxx.entity.serviceflow.BranchNodeCondition;import com.xxx.entity.serviceflow.BranchNodeData;import net.sf.json.JSONObject;import java.util.ArrayList;import java.util.List;public class Test { public static void main(String[] args) { //构建对象 BranchNodeData data = new BranchNodeData(); data.setBranchId(1L); data.setBranchJumpId(10L); data.setBranchMemo("默认"); data.setBranchType("1"); data.setSeq(0); //设置conditionList属性 ListconditionList = new ArrayList<>(); BranchNodeCondition condition = new BranchNodeCondition(); condition.setId(1L); condition.setJudgeType("0"); condition.setParamGroup(1); condition.setParamName("name"); condition.setParamValue("盖伦 与 卡特琳娜"); condition.setPgJudgeType("0"); conditionList.add(condition); data.setConditionList(conditionList); JSONObject json = JSONObject.fromObject(data); System.out.println("BranchNodeData转为json字符串:n" + json); System.out.println("n-------------华丽的分割线-------------n"); //------以下代码为重点,前面的代码只是铺垫------ BranchNodeData o = (BranchNodeData) JSONObject.toBean(json, BranchNodeData.class); System.out.println("json字符串转为BranchNodeData:n" + o.toString() + "n"); //在遍历conditionList属性时报错 for (BranchNodeCondition info : o.getConditionList()) { System.out.println("condition信息为:n" + info); } }}
四、原因
1、JsonObject 对象强转 Java对象,且JsonObject对象中含有数组类型(ArrayList)的属性时出现
2、在转换时不会报错,但是想要拿到转换后的数组时会报这个错误
3、以本篇代码为例,可以看到强转后的conditionList属性类型与原先的属性类型是不一致的(原先类型为:BranchNodeCondition,转换后却是:net.sf.ezmorph.bean.MorphDynaBean)
BranchNodeData转为json字符串:{"branchId":1,"branchJumpId":10,"branchMemo":"默认","branchType":"1","conditionList":[{"id":1,"judgeType":"0","paramGroup":1,"paramName":"name","paramValue":"盖伦 与 卡特琳娜","pgJudgeType":"0"}],"seq":0}-------------华丽的分割线-------------json字符串转为BranchNodeData:BranchNodeData(branchId=1, seq=0, branchType=1, branchMemo=默认, branchJumpId=10, conditionList=[net.sf.ezmorph.bean.MorphDynaBean@396e2f39[ {paramGroup=1, judgeType=0, id=1, paramName=name, paramValue=盖伦 与 卡特琳娜, pgJudgeType=0}]])
五、解决
JsonObject中含有List属性,所以需要用map映射一下
以本篇为例
//注释掉原先转换的代码 //BranchNodeData o = (BranchNodeData) JSONObject.toBean(json, BranchNodeData.class); //定义Map映射 Map> classMap = new HashMap<>(); //Map-Key为实体对象List属性的属性名称 //Map-Value为实体对象List属性的属性类型 classMap.put("conditionList", BranchNodeCondition.class); //指定Map映射 BranchNodeData o = (BranchNodeData) JSONObject.toBean(json, BranchNodeData.class, classMap);