2011-02-14 2 views
7

동일한 문자열 형식을 유지하면서 {"a": 1.0} 문자열을 일반 Java 객체로 읽고 싶습니다. 그러나 시도 할 때 Jackson은 자동으로 내부 표현을 {a = 1}으로 바꿉니다. 즉, {a = 1} 대신 {"a": 1.0}을 인쇄하려면 다음 코드를 어떻게 얻을 수 있습니까? 다른 프로그램 제약으로 인해 Object으로 읽어야합니다.Java with Jackson의 일반 객체 직렬화

import org.codehaus.jackson.map.ObjectMapper; 

public class Main { 

    public static void main(String[] args) { 
     try 
    { 
      ObjectMapper mapper = new ObjectMapper(); 
      Object myObject = mapper.readValue("{\"a\": 1.0}", Object.class); 
      System.out.println(myObject.toString());    
    } 
    catch (Exception e) 
    { 
     e.printStackTrace(); 
     System.err.println(e.getMessage()); 
    } 
    } 

} 
+2

이것은 나에게 의미가 없습니다. Object에는 키 "a"에 대한 속성이 없으므로 어떻게 읽을 수 있습니까? 이 속성으로 클래스를 만들 필요가 없습니까? –

+1

어쩌면 그는 Jackson이 어떻게 든 예상되는 유형을 텔레파시로 추측한다고 가정하고있을 것입니다. 실제로 Object.class 유형은 잭슨과 특별한 처리 방식을 가지고 있습니다 :지도, 목록 및 래퍼 유형 (모든 개체가 분명히 있음)에 "자연스러운") – StaxMan

답변

3

원하는 json 구조와 일치하는 기존 클래스가 필요합니다. 객체가 그러한 클래스가 아닙니다. 이 필요할 경우 여전히 Object로 참조 할 수 있습니다 : 당신이 디버거를 사용하는 경우, 반환 된 개체의 유형 LinkedHashMap 것을 볼 수

Object myObject = mapper.readValue("{\"a\": 1.0}", SomeClass.class); 
2

. 그러면 출력은 LinkedHashMap.toString()입니다.

if(myObject instanceof Map<?, ?>){ 
    final Map<?, ?> map = (Map<?, ?>) myObject; 
    final StringBuilder sb = new StringBuilder("{"); 
    boolean first = true; 
    for(final Entry<?, ?> entry : map.entrySet()){ 
     if(first){ 
      first = false; 
     } else{ 
      sb.append(","); 
     } 
     sb.append("\n\t'") 
      .append(entry.getKey()) 
      .append("':'") 
      .append(entry.getValue()) 
      .append("'"); 
    } 
    if(!first){ 
     sb.append("\n"); 
    } 
    sb.append("}"); 
    System.out.println(sb.toString()); 

} else{ 
    System.out.println(myObject); 
} 

출력 :

당신은지도에 캐스팅하고, 문자열을 직접 만들거나 당신을위한 JSON 문자열을 생성하는 또 다른 반환 형식을 요청할 수 있습니다 있도록 잭슨이 그것을 바꿀 수있는 방법은 없습니다
{ 
    'a':'1.0' 
} 
+3

잭슨은지도 작성을 지원하므로 다음과 같이 할 수 있습니다 :'System.out.println (mapper.writeValueAsString (myObject))'를 호출합니다. – oconnor0

2

잭슨이 JSON을 Object.class로 바인딩하라는 메시지가 표시되면 바로 그 작업을 수행합니다. JSON (또는 어떤 클래스가 사용하기를 원하는 클래스)에 대한 선험적 지식이 없으므로 맵,리스트, 숫자, 부울 및 문자열과 같은 가장 기본적인 Java 유형을 사용해야합니다. 따라서 모든 JSON 객체는 Map으로 표현됩니다. 목록 별 JSON 배열 등.

사용자 지정 개체를 원하면 해당 개체 유형을 지정해야합니다. 또는 직렬화 할 때 명시 적 유형 정보 포함을 가능하게합니다 ("다형성 유형 처리"). 이렇게하면 클래스 이름 또는 유형 이름이 추가되고 정확한 유형으로 역 직렬화하는 데 사용할 수 있습니다.

이렇게하려면 형식 자체 또는 해당 수퍼 유형 중 하나에서 @JsonTypeInfo annotation을 사용해야합니다. 또는 Object 속성 인 경우 속성 (필드 또는 메서드)의 @JsonTypeInfo입니다.

7

생성 된 개체는 다른 주석과 마찬가지로지도가 될 것이므로 toString은보고있는 내용을 생성합니다 ({a = 1}).

{"a":1.0} 
: 찾고있는 나는 당신을 믿는 것을 나에게 제공

System.out.println(mapper.writeValueAsString(myObject)); 

: 사용자의 입력 값에 가까운 무언가를 인쇄하는 코드를 얻으려면, 당신은 다시 같은 뭔가 그것을 밖으로 쓰기 잭슨을 사용할 필요가

즉, Jackson은 입력 문자열을 임의의 Java 객체로 직렬화 해제했습니다. 객체에 toString을 호출하면 해당 객체의 toString이 사용됩니다. Object의 메서드를 사용하는 것을 포함하여 객체가 마음에 들지만 쓸 수 있습니다. 입력 문자열을 재현하려면 Jackson을 사용하여 객체를 직렬화해야합니다.