문자열을 문자열 목록으로 역 직렬화

Sep 23 2020

다음 속성을 포함하는 POJO가 있습니다.

public class Example {
  @JsonProperty("inputFoo")
  private String foo
  @JsonProperty("inputBar")
  private String bar
  @JsonProperty("inputBaz")
  @JsonDeserialize(using = MyDeserializer.class)
  private Set<String> baz
}

이 데이터를 나타 내기 위해 작업중인 JSON은 현재 baz 속성을 단일 문자열로 나타냅니다.

{"inputFoo":"a", "inputBar":"b", "inputBaz":"c"}

Jackson ObjectMapper를 사용하여 JSON을 내 POJO로 변환하려고합니다. JSON의 입력 baz String이 내가 표현하려는 Set에 명확하게 매핑되지 않는다는 것을 알고 있으므로 사용자 지정 Deserializer를 정의했습니다.

public class MyDeserializer extends StdDeserializer<Set<String>> {
   public MyDeserializer(){}

   public MyDeserializer(Class<?> vc) {
      super(vc);
   }

   public Set<String> deserialize(JsonParser p, DeserializationContext cxt) throws IOException, JsonProcessingException {
      String input = p.readValueAs(String.class);
      Set<String> output = new HashSet<>();
      if(input != null) {
         output.add(input);
      }
      return output;
   }
}

세부 정보를 제공 할 수있는 "inputBaz"속성을 참조하는 IllegalArgumentException이 발생합니다. 내 deserializer 구현에 명백한 문제가있는 사람이 있습니까? 감사

답변

2 MichałZiober Sep 22 2020 at 23:33

사용자 정의 디시리얼라이저를 구현할 필요가 없으며 ACCEPT_SINGLE_VALUE_AS_ARRAY 기능을 사용 하십시오 . 세트에서도 작동합니다.

Java 컬렉션 (배열, java.util.Collection) 유형 과 함께 작동하도록 비 배열 (JSON) 값을 강제하는 것이 허용되는지 여부를 결정하는 기능입니다 . 활성화 된 경우 컬렉션 deserializer는 JSON 배열 주변에 "암시 적"이있는 것처럼 배열이 아닌 값을 처리하려고합니다. 이 기능은 호환성 / 상호 운용성을 위해 사용되며 배열에 단일 요소 만있는 경우 JSON 배열을 제외하는 패키지 (예 : XML-JSON 변환기)와 함께 작동합니다. 기능은 기본적으로 비활성화되어 있습니다.

또한보십시오:

  • com.fasterxml.jackson.databind.exc.MismatchedInputException : java.util.ArrayListSTART_OBJECT 토큰에서 인스턴스를 역 직렬화 할 수 없습니다.
Andreas Sep 22 2020 at 23:44

2 개의 생성자를 인수가없는 생성자로 바꿉니다.

public MyDeserializer() {
    super(TypeFactory.defaultInstance().constructCollectionType(Set.class, String.class));
}
pirho Sep 23 2020 at 02:00

ACCEPT_SINGLE_VALUE_AS_ARRAY 제안 된대로 좋은 옵션입니다.

실제 문제가 더 복잡 할 수도 있지만 그렇지 않은 경우 @JsonCreator사용자 지정 deserializer 대신 시도해 볼 수도 있습니다 . 처럼:

public class Example {

    @JsonCreator
    public Example(@JsonProperty("inputFoo") String foo,
            @JsonProperty("inputBar") String bar,
            @JsonProperty("inputBaz") String strBaz) {
        this.foo = foo;
        this.bar = bar;
        this.baz = new HashSet<>();
        baz.add(strBaz);
    }

    private String foo;
    private String bar;
    private Set<String> baz;
}

보다 일반적인 경우에 사용자 지정 deserializer를 구현하는 것을 피할 수 @JsonCreator있지만 여전히 몇 가지 간단한 변환을 수행 할 수 있음을 보여줍니다 .