一、出错原因
当我们利用json解析中的toBean方法时,如果它的属性里面包含复杂对象,那么在我们调用这个复杂对象时就会出现这个错误:java.lang.ClassCastException: net.sf.ezmorph.bean.MorphDynaBean cannot be cast to XXX
二、出错场景
student类,里面有姓名、性别和年龄三个属性和它们对应的get、set方法:
public class Student { private String stuName; private String sex; private Integer age; public String getStuName() { return stuName; } public void setStuName(String stuName) { this.stuName = stuName; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
Teacher类,里面有教师姓名、Student、list集合的Student、map集合的Student
public class Teacher { private String teaName; private Student stu; private List<Student> stuList; private Map<String, Student> stuMap; public String getTeaName() { return teaName; } public void setTeaName(String teaName) { this.teaName = teaName; } public Student getStu() { return stu; } public void setStu(Student stu) { this.stu = stu; } public List<Student> getStuList() { return stuList; } public void setStuList(List<Student> stuList) { this.stuList = stuList; } public Map<String, Student> getStuMap() { return stuMap; } public void setStuMap(Map<String, Student> stuMap) { this.stuMap = stuMap; } }
测试用的json字符串
{ "teaName":"老王", "stu":{ "stuName":"张三", "sex":"男", "age":18 }, "stuList":[ { "stuName":"李四", "sex":"男", "age":18 }, { "stuName":"王五", "sex":"男", "age":18 } ], "stuMap":{ "小明":{ "stuName":"小明", "sex":"男", "age":18 }, "小红":{ "stuName":"小红", "sex":"nü", "age":18 } } }
测试用例,其中的jsonStr使用上面的json字符串:
public class JsonParsingTest { private final static String jsonStr = ""; public static void main(String[] args) { JSONObject jsonObj = JSONObject.fromObject(jsonStr); Teacher teacher = (Teacher)JSONObject.toBean(jsonObj, Teacher.class); testStu(teacher.getStu()); testListStu(teacher.getStuList()); testMapStu(teacher.getStuMap()); } private static void testStu(Student stu) {//正常运行 System.out.println(stu.getStuName()); } private static void testListStu(List<Student> stuList) {//出现ClassCastException异常 for(Student stu : stuList) { System.out.println(stu.getStuName()); } } private static void testMapStu(Map<String, Student> stuMap) {//出现ClassCastException for(String key : stuMap.keySet()) { Student stu = stuMap.get(key); System.out.println(stu.getStuName()); } } }
三、解决方案
一、json转化为带有list集合的复杂对象时出现的ClassCastException异常的解决方案
- 新建一个map对象
- 以list集合的名称作为key,list集合里面的对象的Class作为value存入到map对象里面
- 在将json对象转化为javaBean对象时将新建的map作为最后一个参数传入到toBean方法里面
示例代码如下:
Map<String, Class<?>> classMap = new HashMap<String, Class<?>>(); classMap.put("stuList", Student.class); Teacher teacher = (Teacher)JSONObject.toBean(jsonObj, Teacher.class, classMap);
二、json转化为带有map集合的复杂对象时出现的ClassCastException异常的解决方案
ps.将json对象转为包含复杂map集合的对象比较困难,需要具体情况具体分析,以下是我的解决思路:
- 通过json对象的getJSONObject方法获得需要被转化为map集合的json对象
- 建立一个方法parseJSON2Map,将上一步获得的json对象转为map对象
- 将第二步转化好的map对象set进最开始转化好的javaBean对象中
示例代码如下:
JSONObject jsonObj = JSONObject.fromObject(jsonStr); Teacher teacher = (Teacher)JSONObject.toBean(jsonObj, Teacher.class); Map<String, Student> stuMap = parseJSON2Map(jsonObj.getJSONObject("stuMap")); teacher.setStuMap(stuMap);
将json对象转为map对象方法代码:
Map<String, Student> parseJSON2Map(JSONObject json) { Map<String, Student> tables = new HashMap<String, Student>(); Map<String, Class<?>> classMap = new HashMap<String, Class<?>>(); for(Object key: json.keySet()) { JSONObject value = json.getJSONObject(key.toString()); Student table = (Student)JSONObject.toBean(value, Student.class, classMap); tables.put(key.toString(), table); } return tables; }