복붙노트

[SPRING] Jackson과 주석을 통해 일반 목록 디시리얼라이저를 정의하는 방법은 무엇입니까?

SPRING

Jackson과 주석을 통해 일반 목록 디시리얼라이저를 정의하는 방법은 무엇입니까?

목록 속성을 가진 객체가 있다고 가정 해 보겠습니다.

public class Citizen {
    name
    List<Tickets> tickets
    List<Fines> fines
}

주석을 통해리스트에 대한 일반적인 사용자 정의 디시리얼라이저를 정의하고자합니다.

public class Citizen {
    ...
    @JsonDeserializer(MyListDeserializer<Tickets>) // <-- generic deserializer
    public void setTickets(List<Tickets> tickets) {
        this.tickets = tickets;
    }

    @JsonDeserializer(MyListDeserializer<Fines>) // <-- how can I do that? 
    public void setFines(List<Fines> fines) {
        this.fines = fines;
    }
}

"generic"디시리얼라이저를 만드는 방법을 찾고 있습니다. 두 가지 유형의 목록을 비 직렬화 할 수 있습니다. ContextualDeserializer와 유사하게 JSON을 Jackson과 맵의 다른 유형에 매핑합니다.

마지막 목적은 MyListDeserializer에서 비어있는 문자열을 비 직렬화로 역 직렬화하기 위해 사용자 정의 비 직렬화 논리를 구현하는 것이지만 빈 문자열에 대한 일반적인 접근 방법을 알고 싶습니다.

해결법

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

    1.목록의 요소를 deserialize 할 deserializer 클래스를 지정할 수 있습니다. @JsonDeserializer 주석의 contentUsing 속성을 사용합니다.

    목록의 요소를 deserialize 할 deserializer 클래스를 지정할 수 있습니다. @JsonDeserializer 주석의 contentUsing 속성을 사용합니다.

    public class Citizen {
        ...
        @JsonDeserializer(contentUsing=MyListDeserializer.class) 
        public void setTickets(List<Tickets> tickets) {
            this.tickets = tickets;
        }
    }
    

    디시리얼라이저를 JsonDeserializer 로 확장하고 실제 클래스의 실제 유형을 저장하는 BaseClass에 속성을 지정합니다.

    abstract class BaseTickets {
        String ticketType;
        public String getTicketType()
    }
    
    public class MyListDeserializer extends JsonDeserializer<BaseTickets> {
    
        @Override
        public BaseTickets deserialize(JsonParser jsonParser, DeserializationContext arg1) throws IOException, JsonProcessingException {
            ObjectCodec oc = jsonParser.getCodec();
            JsonNode node = oc.readTree(jsonParser);
            Iterator<JsonNode> elements = node.getElements();
            for (; elements.hasNext();) {
                String type = (String) elements.next().get("ticketType");
    
                if (type.equals()){
                   //create concrete type here
                }
            }
         }
    

    또는 공통 기본 클래스가없는 모든 List 유형에 대해 단일 직 병렬 변환기를 사용하려는 경우 use 속성을 사용하고 MyListDeserializer extends JsonDeserialize 를 사용하십시오. 목록 요소의 유형을 결정하려면 목록에 형식 정보를 추가하는 사용자 지정 serializer를 작성해야합니다. 그런 다음 일반 deserializer에서 사용할 수 있습니다.

    public class Citizen {
        ...
        @JsonDeserializer(using=MyListDeserializer.class)
        @JsonSerializer(using=MyListSerializer.class) 
        public void setTickets(List<Tickets> tickets) {
            this.tickets = tickets;
        }
    }
    
    public class MyListSerializer extends JsonSerializer<Object> {
    
        @Override
        public void serialize(Object list, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
            @SuppressWarnings("rawtypes")
            jgen.writeStartObject();
            String type = getListType(list);
            jgen.writeStringField("listType", type);
            jgen.writeObjectField("list", list)
        }
    }
    

    from https://stackoverflow.com/questions/12937197/how-to-define-a-generic-list-deserializer-through-annotations-with-jackson by cc-by-sa and MIT license