一、场景
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;
@Data
public class BranchNodeData {
private Long branchId;
private Integer seq;
private String branchType;
private String branchMemo;
private Long branchJumpId;
//实体包含List类型的属性
private List<BranchNodeCondition> conditionList;
}
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属性
List<BranchNodeCondition> conditionList = 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<String,Class<?>> classMap = new HashMap<>();
//Map-Key为实体对象List属性的属性名称
//Map-Value为实体对象List属性的属性类型
classMap.put("conditionList", BranchNodeCondition.class);
//指定Map映射
BranchNodeData o = (BranchNodeData) JSONObject.toBean(json, BranchNodeData.class, classMap);