2017-04-18 17 views
2

私はよりよい休止状態の列挙型マッピングが必要でした。thisページは私によく役立ちました(私はintの代わりにchar型を使用しました)。一般的なEnum Jsonの逆シリアル化

次の質問は、どのようにして一般的な方法で列挙型を直列化/逆直列化できますか?性別列挙の

思う:

@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を実装()、にgetCode()とPersistentEnumインタフェースの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

一つの可能​​な解決策は、列挙型のタイプを識別しますPersistentEnumに新しい方法にgetType()を追加することです。

@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

(各列挙のために、我々はfindEnumメソッドに追加する必要があるため)@Justinホセのソリューションは、私が探しているものではありませんが、それは私に良いヒントを与えました。それが動作する可能性があり、この

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

よう

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

とfindEnum: getType場合は、次のように実装されています。テストされておらず、おそらく脆弱です。

関連する問題