복붙노트

[SPRING] 주석을 사용하여 jackson의 비 직렬화 프로세스에서 ACCEPT_SINGLE_VALUE_AS_ARRAY를 적용하는 방법

SPRING

주석을 사용하여 jackson의 비 직렬화 프로세스에서 ACCEPT_SINGLE_VALUE_AS_ARRAY를 적용하는 방법

Jackson의 ACCEPT_SINGLE_VALUE_AS_ARRAY를 (를) 사용하는 클래스의 List 속성에 주석을 사용하는 방법이 있습니까? 나는 봄을 사용하고 있으며 아래 예외를 받고있다.

중첩 예외는 com.fasterxml.jackson.databind.JsonMappingException입니다 : VALUE_STRING 토큰에서 java.util.ArrayList의 인스턴스를 deserialize 할 수 없습니다.

아래에 클래스가 있다고 가정합니다.

public class MyClass {
.
.
private List<String> value;
.
.
}

그리고 내 JSON 구조는 아래와 같습니다.

사례 1 :

[{"operator": "in", "value": ["Active"], "property": "status"}]

사례 2 :

[{"operator": "like", "value": "aba", "property": "desc"}]

프레임 워크가 비 직렬화 할 때이 두 가지 사례를 동일하게 취급하기를 원한다는 것을 알리기 위해 어떤 주석을 사용해야합니까?

최신 정보: 나는 더 명확하게하기 위해이 게시물의 답변을 업데이트로 옮겼다.

해결법

  1. ==============================

    1.@JsonFormat 주석 사용 :

    @JsonFormat 주석 사용 :

    public class MyClass {
    .
    .
    @JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
    private List<String> value;
    .
    .
    }
    

    여기에서 다른 옵션 버전을 확인할 수 있습니다.

    및 필수 (최소 2.7.0)

    2.6.x 용

    @Autowired private ObjectMapper mapper;
    //.....
    
    mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
    

    이 코드를 이니셜 라이저 클래스에 추가하십시오.

    또는 스프링의 빈 구성에서 jackson을 직접 구성 할 수 있습니다.

    이 구성은 문제를 해결할 수 있지만 모든 비 직렬화마다 활성화됩니다.

  2. ==============================

    2.두 경우 모두 처리하고 디시리얼라이저를 사용하여 값 클래스 속성에 주석을 추가 할 수있는 사용자 지정 JsonDeserializer를 만듭니다.

    두 경우 모두 처리하고 디시리얼라이저를 사용하여 값 클래스 속성에 주석을 추가 할 수있는 사용자 지정 JsonDeserializer를 만듭니다.

    디시리얼라이저 :

    public class StringListDeserializer extends JsonDeserializer<List<String>>{
    
        @Override
        public List<String> deserialize(JsonParser parser, DeserializationContext ctxt)
                throws IOException, JsonProcessingException {
    
            List<String> ret = new ArrayList<>();
    
            ObjectCodec codec = parser.getCodec();
            TreeNode node = codec.readTree(parser);
    
            if (node.isArray()){
                for (JsonNode n : (ArrayNode)node){
                    ret.add(n.asText());
                }
            } else if (node.isValueNode()){
                ret.add( ((JsonNode)node).asText() );
            }
            return ret;
        }
    }
    

    내 수업:

    public class MyClass {
        .
        @JsonDeserialize(using = StringListDeserializer.class)
        private List<String> value;
        .
    }
    

    희망이 도움이됩니다.

    BTW : 단 한 건의 주석으로 이러한 문제를 처리하는 방법이 있다면, 나는 또한 그것을 알고 싶습니다.

  3. ==============================

    3.나는 단지 자신의 질문에 명확하게 대답하고있다. 그 중 하나는 특수 효과를 사용할 수 있도록 상위 버전으로 업그레이드하는 것이 었습니다. 내 프로젝트의 종속성 제한으로 인해 그것을 수행 할 수 없습니다.

    나는 단지 자신의 질문에 명확하게 대답하고있다. 그 중 하나는 특수 효과를 사용할 수 있도록 상위 버전으로 업그레이드하는 것이 었습니다. 내 프로젝트의 종속성 제한으로 인해 그것을 수행 할 수 없습니다.

    결과적으로 Michal Foksa의 대답을 기반으로 맞춤 디시리얼라이저를 만들어 내 문제를 해결했습니다. 그 아래 :

    내 재산에 :

    @JsonDeserialize(using = CustomStringDeserializer.class)
    private List<String> value;
    

    그리고 내 디시리얼라이저 :

    public class CustomStringDeserializer extends JsonDeserializer<List<String>>{
    
        @Override
        public List<String> deserialize(JsonParser p, DeserializationContext ctxt)
                throws IOException, JsonProcessingException {
            ObjectMapper mapper = new ObjectMapper();
            mapper.enable(DeserializationFeature. ACCEPT_SINGLE_VALUE_AS_ARRAY);
            return mapper.readValue(p, List.class);
        }
    
    }
    
  4. from https://stackoverflow.com/questions/39041496/how-to-enforce-accept-single-value-as-array-in-jacksons-deserialization-process by cc-by-sa and MIT license