net.sf.json.JSONObject强转后序列化报错java.io.NotSerializableException: net.sf.ezmorph.primitive.CharMorpher

文章描述了一个在将JSONObject转换为实体对象并尝试序列化其包含的List属性时遇到的`NotSerializableException`异常。问题的根本原因是List中存储的不是预期的实体类型,而是`MorphDynaBean`。解决方案是通过定义Map映射来确保转换后的List属性类型正确,从而使其可序列化。
摘要由CSDN通过智能技术生成


一、场景

1、将net.sf.json.JSONObject转为实体对象

2、将实体对象的List属性序列化(List属性的实体类以实现Serializable接口)

3、序列化报错-java.io.NotSerializableException: net.sf.ezmorph.primitive.CharMorpher


二、报错信息

java.io.NotSerializableException: net.sf.ezmorph.primitive.CharMorpher
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
	at java.util.ArrayList.writeObject(ArrayList.java:766)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1140)
	at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1496)
	at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
	at java.util.HashMap.internalWriteEntries(HashMap.java:1793)
	at java.util.HashMap.writeObject(HashMap.java:1363)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1140)
	at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1496)
	at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
	at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
	at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
	at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
	at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
	at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
	at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)

三、代码

1、实体

package com.xxx.entity.serviceflow;

import lombok.Data;

import java.io.Serializable;


@Data
//注意:实体以实现Serializable接口
public class BranchNodeCondition implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;

    private String paramName;

    private String judgeType;
	
    private String paramValue;

    private Integer paramGroup;

    private String pgJudgeType;
}

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序列化(执行到这里报错)
        ListUtil.deepCopy(o.getConditionList());
    }
}


四、原因

1、从表面上看List集合存储的是BranchNodeCondition类型的对象,该类确实已经实现Serializable接口,正常应该是可以序列化的

2、但实际上List集合存储的是net.sf.ezmorph.bean.MorphDynaBean类型的对象,该类可没有实现Serializable接口

为什么?

3、JsonObject 对象强转 Java对象,且JsonObject对象中含有数组类型(ArrayList)的属性时会出现这种情况

4、在转换时不会报错,
但是想要拿到转换后的数组进行操作(例如for循环)时会报错java.lang.ClassCastException: net.sf.ezmorph.bean.MorphDynaBean cannot be cast to com.xxx.entity.xxx
序列化也会报错java.io.NotSerializableException: net.sf.ezmorph.primitive.CharMorpher

5、以本篇代码为例,可以看到强转后的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字符串转为BranchNodeDataBranchNodeData(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);

使用Map映射之后的List集合就可以序列化了

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值