JsonNode를 POJO로 변환


143

이것은 조금 이상한 것처럼 보일 수 있습니다,하지만 난 / 변환을지도 할 수있는 효율적인 방법을 찾고 있어요 JsonNodePOJO.

내 모델 정보 중 일부를 json 파일에 저장하고 내 모델의 두 가지 버전을 지원해야합니다.

내가하는 일은 json 파일을 JsonNode의 메모리에로드하고 최신 버전의 모델과 일치하도록 몇 가지 버전 관리 전략을 적용하는 것입니다.

    ObjectMapper mapper = new ObjectMapper();
    BufferedReader fileReader = new BufferedReader(new FileReader(projPath));

    JsonNode rootNode = mapper.readTree(fileReader);

    //Upgrade our file in memory
    applyVersioningStrategy(rootNode);

    ProjectModel project = mapJsonNodeToProject(rootNode);

더 빠른 방법이 없다면, 아마도 JsonNodes내 모델에 수동으로 적용하는 것입니다.

답변:


264

Jackson 2.4에서는 다음과 같이 변환 할 수 있습니다.

MyClass newJsonNode = jsonObjectMapper.treeToValue(someJsonNode, MyClass.class);

jsonObjectMapper잭슨은 어디에 있습니까 ObjectMapper?


이전 버전의 Jackson에서는

MyClass newJsonNode = jsonObjectMapper.readValue(someJsonNode, MyClass.class);

19
불행히도 readValue ()와 같은 treeToValue (TreeNode n, TypeReference <T> type) 변형은 없습니다. 제네릭으로 더 복잡한 유형을 다루는 사람에게는 나쁜 소식이 있습니다. (
Espinosa

13
@Espinosa jackson-databind # 1294 에서는 다음과 같은 것을 원할 것입니다jsonObjectMapper.readValue(jsonObjectMapper.treeAsTokens(someJsonNode), someTypeReference)
M. Justin

이전 버전의 경우 :objectMapper.treeToValue(jsonNode, MyClass.class)
amod

2
StdDeserializer에서이 방법을 사용할 수도 있습니다 p.codec.treeToValue.
galcyurio

@icedtrees jsonObjectMapper는 JsonObjectMapper의 인스턴스이거나 단지 ObjectMapper입니다
KNDheeraj

8

트릭을 수행해야합니다.

mapper.readValue(fileReader, MyClass.class);

내가 가진 것을 사용하고 있기 때문에 내가해야 말을 String하는 안 BufferedReader하지만 작업 계속해야한다.

내 코드는 다음과 같습니다.

String inputString = // I grab my string here
MySessionClass sessionObject;
try {
    ObjectMapper objectMapper = new ObjectMapper();
    sessionObject = objectMapper.readValue(inputString, MySessionClass.class);

다음은 해당 호출에 대한 공식 문서입니다. http://jackson.codehaus.org/1.7.9/javadoc/org/codehaus/jackson/map/ObjectMapper.html#readValue(java.lang.String, java.lang.Class)

당신이 인스턴스를 할 때 당신은 또한 사용자 정의 디시리얼라이저를 정의 할 수 있습니다 ObjectMapper: http://wiki.fasterxml.com/JacksonHowToCustomDeserializers

편집 : 방금 다른 것을 기억했습니다. 객체가 가지고있는 것보다 많은 속성을 POJO가지고 있고 여분의 것을 무시하고 싶다면 이것을 설정하고 싶을 것입니다 :

    objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);

또는 설정할 속성을 찾을 수 없다는 오류가 발생합니다.


CustomDeserializer를 사용하면 두통을 많이 줄일 수 있습니다! 또한 약간의 수정만으로도 버전 관리 전략을 적용 할 수 있습니다. 감사!
Alexandre

5
구문은 다음과 같습니다. com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper (); mapper.disable (com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
llambda

@llambda 좋은 지적! 1.7.9 버전부터 ObjectMapper를 만지지 않았습니다. 몇 가지 버전으로 인해 답변이 오래 된 것 같습니다. 사용중인 Jackson 버전을 확인하십시오.
Eric Barr

@EricBarr, Jackson v1.9.11을 사용하고 있으며 답변의 구문이 해당 버전에 맞는 것입니다. 아마도 그들은 사물을 바꾸려고 노력했고 새로운 버전에서 다시 되 돌렸을 것입니다
Ivaylo Slavov

5

org.codehaus.jackson을 사용하는 경우 1.6 이후 가능합니다. 당신이 가진 POJO에 JsonNode을 변환 할 수 있습니다 ObjectMapper#readValue: http://jackson.codehaus.org/1.9.4/javadoc/org/codehaus/jackson/map/ObjectMapper.html#readValue(org.codehaus.jackson.JsonNode , 자바. lang.Class)


    ObjectMapper mapper = new ObjectMapper();
    JsonParser jsonParser = mapper.getJsonFactory().createJsonParser("{\"foo\":\"bar\"}");
    JsonNode tree = jsonParser.readValueAsTree();
    // Do stuff to the tree
    mapper.readValue(tree, Foo.class);

5
이 방법은 2.4.4에서 누락 된 것 같습니다
Kevin Wittek

1
버전 2 솔루션에 대해서는 아래 icedtrees의 답변을 참조하십시오.
Tim Büthe


3
String jsonInput = "{ \"hi\": \"Assume this is the JSON\"} ";
com.fasterxml.jackson.databind.ObjectMapper mapper =
    new com.fasterxml.jackson.databind.ObjectMapper();
MyClass myObject = objectMapper.readValue(jsonInput, MyClass.class);

JSON 입력의 POJO보다 많은 속성이 있고 Jackson 2.4의 추가 기능을 무시하려는 경우 다음과 같이 ObjectMapper를 구성 할 수 있습니다. 이 구문은 이전 Jackson 버전과 다릅니다. (잘못된 구문을 사용하면 아무 것도 자동으로 수행되지 않습니다.)

mapper.disable(com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNK‌​NOWN_PROPERTIES);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.