2017-04-18 146 views
2

我需要一个更好的休眠枚举映射和this页我受益匪浅(除非我用的char类型,而不是INT)。通用枚举的Json反序列化

下一个问题是我如何可以序列化/在一个通用的方法反序列化一个枚举?

认为一个性别枚举的:一个PersistentEnum接口的

@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; 
    } 

} 

它实现的getName(),引用代码()和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(); 
    } 
} 

,但我怎么能反序列化Java 6的?在java中8,我会一个静态方法添加到PersistentEnum接口。

public class PersistentEnumDeserializer extends JsonDeserializer<PersistentEnum> { 

    @Override 
    public PersistentEnum deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { 
     JsonNode node = jp.getCodec().readTree(jp); 
     //String value = node.get("name").asText(); 
     //TODO Somehow I need to get Gender.MALE if the json is {"name":"MALE","code":"M","display":"Male"} 
     return null; 
    } 

} 

回答

1

一种可能的解决方案是getType()添加一个新的方法来PersistentEnum将识别枚举类型。

@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(); 
} 
} 

解串器可以写成如下所示。

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; 
     } 
    } 

} 
0

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

@Override 
public String getType() { 
    return getClass().getSimpleName(); 
} 

和findEnum这样

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; 
} 

它可能工作。未经测试并可能脆弱。