Java 泛型枚举Json反序列化
我需要一个更好的hibernate枚举映射,页面对我很有用(除了我使用了char类型而不是int) 下一个问题是如何以通用方式序列化/反序列化枚举 想想性别枚举: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
@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;
}