2017-12-23 9 views
3

私はこのように見えるenum Statusを持っているとしましょう。ジャクソンは異なる列を同じ列挙定数に逆直列化します

public enum Status { 
    SUCCESS, 
    FAIL, 
    RETRY, 
    UNKNOWN 
} 

私は、次の例のようになります。JSONからstatusプロパティを受け付けております。 //有効な場合

  • {"status":"success"}は、Status.SUCCESS
  • {"status":"fail"} //有効な場合に、Status.RETRY

にデシリアライズしかし、他の値がすべき、Status.FAIL

  • {"status":"retry"} //有効な場合にデシリアライズデシリアライズデシリアライズされてStatus.UNKNOWNになります。例。

    • {"status":"blabla"} //無効な場合、私はカスタムデシリアライザを書き込むことによってそれを行うことができます知っているが、私は試してみたStatus.UNKNOWN

    にデシリアライズ、Status.UNKNOWN

  • {"status":"John"} //無効な場合にデシリアライズ私のプログラムには多くの列挙型があり、それぞれのカスタムデシリアライザを必要とすることは過度のものになることを避けるためです。

    理想的には、任意の文字列に一致する正規表現のコンストラクタ(「成功」、「失敗」、「再試行」を除く)。

    カスタムデシリアライザを作成せずにJacksonとやり取りする方法はありますか?

  • 答えて

    1

    あなたの列挙型のすべてがUNKNOWN値を持っている場合、あなたはこのような1つのカスタムデシリアライザ書くことができます。

    class EnumDeserializer extends JsonDeserializer<Enum> { 
    
        private final Class<? extends Enum> enumType; 
    
        public EnumDeserializer(Class<? extends Enum> enumType) { 
         this.enumType = enumType; 
        } 
    
        @Override 
        public Enum deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { 
         try { 
          String stringValue = jp.getValueAsString().toUpperCase(); 
          return Enum.valueOf(enumType, stringValue.toUpperCase()); 
         } catch (IllegalArgumentException e) { 
          return Enum.valueOf(enumType, "UNKNOWN"); 
         } 
        } 
    } 
    

    をし、ユーザそれにあなたのマッパーを設定します。

    SimpleModule module = new SimpleModule(); 
    module.setDeserializerModifier(new BeanDeserializerModifier() { 
        @Override 
        public JsonDeserializer<Enum> modifyEnumDeserializer(DeserializationConfig config, 
                     final JavaType type, 
                     BeanDescription beanDesc, 
                     final JsonDeserializer<?> deserializer) { 
    
         return new EnumDeserializer((Class<Enum<?>>) type.getRawClass()); 
        } 
    }); 
    
    ObjectMapper mapper = new ObjectMapper(); 
    mapper.registerModule(module); 
    

    代わりにあなたはジャクソンのデシリアライズを使用することができます未知の列挙型プロパティのデフォルト値を設定する機能:

    enum MyEnum { A, B, @JsonEnumDefaultValue UNKNOWN } 
    ... 
    final ObjectMapper mapper = new ObjectMapper(); 
    mapper.enable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE); 
    
    MyEnum value = mapper.readValue("\"foo\"", MyEnum.class); 
    assertSame(MyEnum.UNKNOWN, value); 
    

    しかし、このような方法では、すべての列挙型をデフォルト値の@JsonEnumDefaultValue注釈を使用するように変更する必要があります。また、デフォルトでは小文字の列挙型の値は処理されません。

    +0

    この質問をどのように把握できますか?私は2日間、jackson-databindのソースコードをトレースしようとしましたが、何も見つけませんでした.... – LoveTW

    関連する問題