[alibaba/fastjson]对enum对象的序列化与反序列化

2025-11-11 602 views
0

在对enum序列化时,实现JSONSerializable接口后,只有toJSONString方法有效,toJSON无效. 看了下代码,原因应该在于toJSON方法中的 if (clazz.isEnum()) { return ((Enum) javaObject).name(); }. 反序列化时,只能根据enum的name和ordinal去反序列化. fastjson version:1.2.37 test case:

public enum Sex implements JSONSerializable {

    NONE("0","NONE"),MAN("1","男"),WOMAN("2","女");
    private final String code;
    private final String des;
    private Sex(String code, String des) {
        this.code = code;
        this.des = des;
    }

    public String getCode() {
        return code;
    }

    public String getDes() {
        return des;
    }

    @Override
    public void write(JSONSerializer serializer, Object fieldName, Type fieldType, int features) throws IOException {

        JSONObject object = new JSONObject();
        object.put("code", code);
        object.put("des", des);
        serializer.write(object);

    }
}
public class Student implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 3083987595140340233L;

    private Long id;

    private String name;

    private Sex sex;
        // getter and setter
    public static void main(String[] args) {
        Student student = new Student();
        student.setName("name");
        student.setId(1L);
        student.setSex(Sex.MAN);
        System.out.println(JSON.toJSON(student).toString());
        System.out.println(JSON.toJSONString(student));
        String str1 = "{\"id\":1,\"name\":\"name\",\"sex\":\"MAN\"}";
        Student stu1 = JSON.parseObject(str1,Student.class);
        System.out.println(JSON.toJSONString(stu1));
        String str2 = "{\"id\":1,\"name\":\"name\",\"sex\":{\"code\":\"1\",\"des\":\"男\"}}";
        JSON.parseObject(str2, Student.class);
    }
}

输出: {"sex":"MAN","name":"name","id":1} {"id":1,"name":"name","sex":{"code":"1","des":"男"}} {"id":1,"name":"name","sex":{"code":"1","des":"男"}} Exception in thread "main" com.alibaba.fastjson.JSONException: parse enum ......

回答

5

在 1.2.39 版本中如果不实现JSONSerializable,而是使用 @JSONType(serializeEnumAsJavaBean = true) 注解的话,仍然有该问题。只有toJSONString方法有效,toJSON无效。

1
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
//@EnableEntityEvent
public class TestUser extends BaseCustomerEntity {

    @TableField("name")
    private String name;

    @TableField("sex")
    private GenderEnum sex;

}

@Dict(id = "genderEnum", comments = "性别枚举")
@Getter
@AllArgsConstructor
public enum GenderEnum implements EnumDict<Integer> {

    MAN(1, "男"),

    WOMAN(2, "女"),

    ;

    @EnumValue
    private Integer code;
    private String desc;
}

// test case
@Test
    public void test1() {
        String userJson = "{\"name\" :  \"张三\", \"sex\" :  2}";
        TestUser testUser = JSON.parseObject(userJson, TestUser.class);
        System.out.println(testUser);

    }

fastjson版本:1.2.73 输出报错: com.alibaba.fastjson.JSONException: parse enum com.ctg.crm.common.enums.GenderEnum error, value : 2

1
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
//@EnableEntityEvent
public class TestUser extends BaseCustomerEntity {

    @TableField("name")
    private String name;

    @TableField("sex")
    private GenderEnum sex;

}

@Dict(id = "genderEnum", comments = "性别枚举")
@Getter
@AllArgsConstructor
public enum GenderEnum implements EnumDict<Integer> {

    MAN(1, "男"),

    WOMAN(2, "女"),

    ;

    @EnumValue
    private Integer code;
    private String desc;
}

// test case
@Test
    public void test1() {
        String userJson = "{\"name\" :  \"张三\", \"sex\" :  2}";
        TestUser testUser = JSON.parseObject(userJson, TestUser.class);
        System.out.println(testUser);

    }

fastjson版本:1.2.73 输出报错: com.alibaba.fastjson.JSONException: parse enum com.ctg.crm.common.enums.GenderEnum error, value : 2

1.2.83 仍然有该问题