我需要一个更好的hibernate枚举映射,并且this页面很好地为我服务(除了我使用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();
}
}
但是如何在 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;
}
}
答案 0 :(得分: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;
}
}
}
答案 1 :(得分:0)
虽然@Justin Jose的解决方案不是我想要的解决方案(因为对于我们需要添加到findEnum方法的每个枚举),它给了我一个很好的提示。
如果{new:true}
实现如下:
getType
和findEnum这样
@Override
public String getType() {
return getClass().getSimpleName();
}
它可能有用。未经测试且可能易受攻击。