2017-12-23 3 views
3

enum Status이 이렇게 생겼다고 가정 해 봅니다.잭슨 (Jackson)이 다른 문자열을 동일한 열거 형 상수로 deserialize합니다.

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

다음 예와 같이 보이는 JSON에서 status 속성을 받았습니다. // 유효한 경우

  • {"status":"success"}Status.SUCCESS
  • {"status":"fail"} // 유효한 경우에, Status.RETRY

에 역 직렬화 그러나 다른 값이해야, Status.FAIL

  • {"status":"retry"} // 유효한 경우에 역 직렬화 역 직렬화 deserialize되어 Status.UNKNOWN가됩니다. 예. // 유효하지 않은 경우

    • {"status":"blabla"}은 내가 정의 디시리얼라이저를 작성하여 그것을 할 수 알고 Status.UNKNOWN

    Status.UNKNOWN

  • {"status":"John"} // 유효하지 않은 경우에, 직렬화 직렬화, 그러나 나는 시도 할 것 왜냐하면 나는 많은 것을 가지고 있기 때문에 내 프로그램에 많은 enum이 있고, 각각에 대해 커스텀 디시리얼라이저가 필요하다면 과잉이 될 수있다.

    "success", "fail"및 "retry"를 제외한 모든 문자열과 일치하는 정규식의 생성자 일종 이상적입니다.

    사용자 지정 디시리얼라이저를 작성하지 않고 Jackson과 함께 할 수 있습니까?

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

    를 그리고 사용자가 그것에게 매퍼를 구성 : 당신의 열거의 모든 UNKNOWN 값이있는 경우

  • 답변

    1

    , 당신은 다음과 같이 하나의 사용자 정의 디시리얼라이저를 작성할 수

    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

    이 질문에 대한 답을 어떻게 얻을 수 있습니까? 나는 이틀 동안 jackson-databind의 소스 코드를 추적하려고했지만 아무 것도 찾지 않았다. – LoveTW

    관련 문제