Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 泛型枚举Json反序列化_Java_Json_Enums_Jackson - Fatal编程技术网

Java 泛型枚举Json反序列化

Java 泛型枚举Json反序列化,java,json,enums,jackson,Java,Json,Enums,Jackson,我需要一个更好的hibernate枚举映射,页面对我很有用(除了我使用了char类型而不是int) 下一个问题是如何以通用方式序列化/反序列化枚举 想想性别枚举: @JsonSerialize(using = PersistentEnumSerializer.class) @JsonDeserialize(using = PersistentEnumDeserializer.class) public enum Gender implements PersistentEnum { MA

我需要一个更好的hibernate枚举映射,页面对我很有用(除了我使用了char类型而不是int)

下一个问题是如何以通用方式序列化/反序列化枚举

想想性别枚举:

@JsonSerialize(using = PersistentEnumSerializer.class)
@JsonDeserialize(using = PersistentEnumDeserializer.class)
public enum Gender implements PersistentEnum {

    MALE("M", "Male"), FEMALE("F", "Female");

    private String code;

    private String display;

    Gender(String code, String display) {
        this.code = code;
        this.display = display;
    }

    public String getName() {
        return name();
    }

    public String getCode() {
        return code;
    }

    public String getDisplay() {
        return display;
    }

    public String toString() {
        return display;
    }

}
实现PersistentEnum接口的getName()、getCode()和getDisplay()方法。序列化很容易:

public class PersistentEnumSerializer extends JsonSerializer<PersistentEnum> {

    @Override
    public void serialize(PersistentEnum object, JsonGenerator generator, SerializerProvider provider) throws IOException, JsonProcessingException {
        generator.writeStartObject();
        generator.writeFieldName("name");
        generator.writeString(object.getName());
        generator.writeFieldName("code");
        generator.writeString(object.getCode());
        generator.writeFieldName("display");
        generator.writeString(object.getDisplay());
        generator.writeEndObject();
    }
}

一个可能的解决方案是将一个新方法
getType()
添加到
persistentemum
中,该方法将标识枚举的类型

@JsonSerialize(using = PersistentEnumSerializer.class)
@JsonDeserialize(using = PersistentEnumDeserializer.class)
public enum Gender implements PersistentEnum {
    @Override
    public String getType() {
        return "gender";
    }
}
序列化程序还应修改为在序列化时包含类型

public class PersistentEnumSerializer extends JsonSerializer<PersistentEnum> {

@Override
public void serialize(PersistentEnum object, JsonGenerator generator, SerializerProvider provider) throws IOException, JsonProcessingException {
    generator.writeStartObject();
    generator.writeFieldName("name");
    generator.writeString(object.getName());
    generator.writeFieldName("code");
    generator.writeString(object.getCode());
    generator.writeFieldName("display");
    generator.writeString(object.getDisplay());
    generator.writeFieldName("type");
    generator.writeString(object.getType());
    generator.writeEndObject();
}
}
公共类PersistentEnumSerializer扩展JsonSerializer{
@凌驾
public void serialize(persistentemum对象、JsonGenerator生成器、SerializerProvider提供程序)引发IOException、JsonProcessingException{
generator.writeStartObject();
生成器。writeFieldName(“名称”);
generator.writeString(object.getName());
generator.writeFieldName(“代码”);
generator.writeString(object.getCode());
generator.writeFieldName(“显示”);
writeString(object.getDisplay());
generator.writeFieldName(“类型”);
generator.writeString(object.getType());
generator.writeEndObject();
}
}
反序列化程序可以按如下所示编写

    public class PersistentEnumDeserializer extends JsonDeserializer<PersistentEnum> {

    @Override
    public PersistentEnum deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        JsonNode node = jp.getCodec().readTree(jp);
        return findEnum(node.get("type").asText(), node.get("name").asText());
    }

    private PersistentEnum findEnum(String type, String name) {
        switch (type) {
        case "gender":
            return Gender.valueOf(name);
        // handle other types here.
        default:
            return null;
        }
    }

}
公共类PersistentEnumDeserializer扩展JsonDeserializer{
@凌驾
公共PersistentEnum反序列化(JsonParser jp,DeserializationContext ctxt)引发IOException,JsonProcessingException{
JsonNode节点=jp.getCodec().readTree(jp);
返回findEnum(node.get(“type”).asText(),node.get(“name”).asText());
}
私有PersistentEnum findEnum(字符串类型、字符串名称){
开关(类型){
“性别”一案:
返回性别。valueOf(姓名);
//在这里处理其他类型。
违约:
返回null;
}
}
}

虽然@Justin Jose的解决方案不是我想要的(因为对于我们需要添加到findEnum方法中的每个枚举),但它给了我一个很好的提示。 如果
getType
是这样实现的:

@Override
public String getType() {
    return getClass().getSimpleName();
}
像这样的芬迪纳姆

private PersistentEnum findEnum(String type, String name) {
    Class<?> c = null;
    try {
        c = Class.forName("enums." + type); //Assuming all PersistentEnum's are in "enums" package
        if (PersistentEnum.class.isAssignableFrom(c)) {
            Method method = c.getMethod("name");
            for (Object object : c.getEnumConstants()) {
                Object enumName = method.invoke(object);
                if (name.equals(enumName))
                    return (PersistentEnum) object;
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}
private persistennum findEnum(字符串类型、字符串名称){
c类=空;
试一试{
c=Class.forName(“enums.+type);//假设所有persistentum都在“enums”包中
if(persistentemum.class.isAssignableFrom(c)){
方法=c.getMethod(“名称”);
对于(对象:c.getEnumConstants()){
Object enumName=method.invoke(对象);
if(name.equals(enumName))
返回(PersistentEnum)对象;
}
}
}捕获(例外e){
e、 printStackTrace();
}
返回null;
}
这可能有用。未经测试,可能易受攻击

private PersistentEnum findEnum(String type, String name) {
    Class<?> c = null;
    try {
        c = Class.forName("enums." + type); //Assuming all PersistentEnum's are in "enums" package
        if (PersistentEnum.class.isAssignableFrom(c)) {
            Method method = c.getMethod("name");
            for (Object object : c.getEnumConstants()) {
                Object enumName = method.invoke(object);
                if (name.equals(enumName))
                    return (PersistentEnum) object;
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}