복붙노트

[SPRING] POJO가 인스턴스 변수로 JSON 필드를 포장

SPRING

POJO가 인스턴스 변수로 JSON 필드를 포장

내가 클래스 인스턴스 변수에 특정 JSON 필드를 매핑하는 것을 시도하고있다.

내 샘플 Person 클래스는 아래와 같다 :

public class Person {
   private String name;
   private Address address;

   //many more fields 

   //getters and setters
}

샘플 주소 클래스입니다 :

public class Address {
   private String street;
   private String city;
   //many more fields 

   // getters and setters
}

json으로 개체는 "주소"필드를 포함하지 않는 내 사람 클래스에 직렬화 복원합니다. 그것은 다음과 같습니다

{
"name":"Alexander",
"street":"abc 12",
"city":"London"
}

주소 필드가 적절히 매핑 된 사람의 POJO에 JSON을 역 직렬화하는 방법이 있나요?

내가 여기 이렇게 많은 게시물에서 언급 한 바와 같이 디시리얼라이저 사용자 지정 주소를 사용하고 있습니다. 그러나, "주소"필드를 포함하지 않는 JSON 객체로 호출되는 아닙니다.

나는 그것이 좋은 해결책이 아니다, 그러나 내 실제 프로젝트에 수동으로 각 필드를 매핑 JsonNode를 사용하여이 문제를 해결했다.

모든 작업은 잭슨을 사용하여 이러한 문제에 대한 주위 있습니까? 게다가이 질문은 내가 집중적으로 솔루션을 검색하고 아직 보지 못한 것만 큼 내 대신 다음 사과하기 전에 요청 된 경우. .

해결법

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

    1.@JsonUnwrapped 주석이 문제에 대한 소개되었다. 모델:

    @JsonUnwrapped 주석이 문제에 대한 소개되었다. 모델:

    class Person {
        private String name;
    
        @JsonUnwrapped
        private Address address;
    
        // getters, setters, toString
    }
    class Address {
        private String street;
        private String city;
    
        // getters, setters, toString
    }
    

    용법:

    ObjectMapper mapper = new ObjectMapper();
    String json = "{\"name\":\"Alexander\",\"street\":\"abc 12\",\"city\":\"London\"}";
    System.out.println(mapper.readValue(json, Person.class));
    

    인쇄물:

    Person{name='Alexander', address=Address{street='abc 12', city='London'}}
    

    더 많은 정보 읽기 :

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

    2.어떻게 주소 필드는 항상 값이 포함되어 있는지 확인하는 방법 : 당신이 정말 여기가 아니라 일반적인 자바 문제를 역 직렬화 문제가 있다고 생각하지 않습니다. 당신이해야 할 모든 사람 생성자에 기본 값 중 하나를 할당 주소, 또는 생성하고 Person.getAddress 방법에 주소에 대한 기본 값을 할당합니다.

    어떻게 주소 필드는 항상 값이 포함되어 있는지 확인하는 방법 : 당신이 정말 여기가 아니라 일반적인 자바 문제를 역 직렬화 문제가 있다고 생각하지 않습니다. 당신이해야 할 모든 사람 생성자에 기본 값 중 하나를 할당 주소, 또는 생성하고 Person.getAddress 방법에 주소에 대한 기본 값을 할당합니다.

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

    3.이 사람과 같은 수준의 모든 주소 필드가에 대한 평면 JSON 수 있도록 나는 당신의 문제를 이해했다. 이 정확하지 않더라도 그래서 이것은 당신에게 도움이 될 수 있습니다. JsonDeserializer 잘 할 것입니다하지만 당신은 모든 필드는 수준이기 때문에 사람에 적용해야합니다.

    이 사람과 같은 수준의 모든 주소 필드가에 대한 평면 JSON 수 있도록 나는 당신의 문제를 이해했다. 이 정확하지 않더라도 그래서 이것은 당신에게 도움이 될 수 있습니다. JsonDeserializer 잘 할 것입니다하지만 당신은 모든 필드는 수준이기 때문에 사람에 적용해야합니다.

    이 같은 :

    public class CustomDeserializer extends JsonDeserializer<Person> {
    
        // need to use separate ObjectMapper to prevent recursion
        // this om will not be registered with this custom deserializer
        private final ObjectMapper om;
        {
            om = new ObjectMapper();
            // this is needed because flat json contains unknown fields
            // for both types.
            om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        }
    
        @Override
        public Person deserialize(JsonParser parser, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
            // make a string of json tree so not any particular object
            String json = om.readTree(parser).toString();
            // deserialize it as person (ignoring unknown fields)
            Person person = om.readValue(json, Person.class);
            // set address deserializing it from teh same string, same manner
            person.setAddress(om.readValue(json, Address.class));
            return person;
        }
    
    }
    

    물론 이것은 유일한 방법은 아니다 최고의 성능을하지 않을 수도 있지만, 그것은 당신이 사용자 정의 디시리얼라이저의 직렬화 복원을하는 방법에 대해 전용입니다. 당신의 사람 및 주소 객체 (10 개) 필드처럼 참하는 경우이를 사용하여 각은 문제가되지 않습니다.

    최신 정보

    귀하의 예제 데이터를 기반으로 - - 나는 귀하의 경우라고 생각 마이클 Ziober의  대답은 최선이 될 수 있지만 당신은 당신의 데이터를 풀기 일반보다 더 복잡한 처리를 필요로하는 경우 당신은 내가되게 어떻게 든 같이 Person 클래스를 역 직렬화 할 필요가있다.

  4. from https://stackoverflow.com/questions/54370637/wrapping-json-fields-into-instance-variable-of-a-pojo by cc-by-sa and MIT license