문자열을 문자열 목록으로 역 직렬화
다음 속성을 포함하는 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 구현에 명백한 문제가있는 사람이 있습니까? 감사
답변
사용자 정의 디시리얼라이저를 구현할 필요가 없으며 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 토큰에서 인스턴스를 역 직렬화 할 수 없습니다.
2 개의 생성자를 인수가없는 생성자로 바꿉니다.
public MyDeserializer() {
super(TypeFactory.defaultInstance().constructCollectionType(Set.class, String.class));
}
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있지만 여전히 몇 가지 간단한 변환을 수행 할 수 있음을 보여줍니다 .