2012-05-29 2 views
10

를 사용하여 addional 포장을 추가 나는 다음과 같은 클래스가 : 기본적으로 잭슨을 사용하여 JSON에 인스턴스를 변환 할 때포스 잭슨 주석

public class Message { 
    private String text; 

    public String getText() { 
     return text; 
    } 

    public void setText(String text) { 
     this.text = text; 
    }  
} 

내가 얻을 : 내가 좋아하는 것

{"text":"Text"} 

이 얻을 :
{"message":{"text":"Text"}} 

은 내 목표를 달성하기 위해 사용할 수있는 JAXB/잭슨 주석이 있습니까? 해결 방법으로

, 내가 다른 클래스 내 클래스를 래핑 할 수 있습니다

public class MessageWrapper { 
    private Message message; 

    public Message getMessage() { 
     return message; 
    } 

    public void setMessage(Message message) { 
     this.message = message; 
    } 
} 

또는 더 일반적인 솔루션 :

public class JsonObjectWrapper<T> { 
    /** 
    * Using a real map to allow wrapping multiple objects 
    */ 
    private Map<String, T> wrappedObjects = new HashMap<String, T>(); 

    public JsonObjectWrapper() { 
    } 

    public JsonObjectWrapper(String name, T wrappedObject) { 
     this.wrappedObjects.put(name, wrappedObject); 
    } 

    @JsonAnyGetter 
    public Map<String, T> any() { 
     return wrappedObjects; 
    } 

    @JsonAnySetter 
    public void set(String name, T value) { 
     wrappedObjects.put(name, value); 
    } 
} 

과 같이 사용할 수있는 :

Message message = new Message(); 
message.setText("Text"); 
JsonObjectWrapper<Message> wrapper = new JsonObjectWrapper<Message>("message", message); 

달성 할 수있는 JAXB/Jackson 주석이 있습니까? 내 목표?

감사합니다. 해결 방법에

답변

12

: 당신이 절대적으로 사람들의 getter/setter를 필요로하지 않는, 그래서 그냥 할 수 :

public class MessageWrapper { 
    public Message message; 
} 

을 혹은 간이 생성자 추가 포장을 추가하는 방법이 있습니다

public class MessageWrapper { 
    public Message message; 
    @JsonCreator 
    public MessageWrapper(@JsonProperty("message") Message m) { 
     message = m; 
    } 
} 

너무; 1.9로 SerializationConfig.Feature.WRAP_ROOT_ELEMENTDeserializationConfig.Feature.UNWRAP_ROOT_ELEMENT을 사용할 수 있습니다. 당신은 (는 수식어가 붙지 않은 클래스 이름은 단순히 기본적으로) 래퍼 이름을 변경하려는 경우, 당신은

잭슨 2.0 더욱 동적 ObjectReaderObjectWriter를 통해 옵션과 JAX-RS 주석을 추가 @JsonRootName 주석을 사용할 수 있습니다.

+0

StaxMan, 1.9 혼자'DeserializationConfig.Feature.UNWRAP_ROOT_ELEMENT' 기능 또는 주석 '의 추가를 설정하기 위해 우리를 필요로 @JsonRootName '도 필요합니까? – asgs

+1

나는 UNWRAP만으로도 충분하다는 것을 검증해야 할 것이다. 질문은 이름이 맵핑되어야하는지 여부입니다. 그러나'@ JsonRootName'이 없어도 기본 이름이 존재합니다 (간단한 클래스 이름). 제대로 작동 할 수 있습니다. – StaxMan

+0

그것이 효과가있다! 고마워. – asgs

4

레이블이 지정된 개체로 클래스를 래핑하는 간단한 목표를 위해 사용자 지정 직렬화를 작성해야한다는 것을 알면 슬 was습니다. 커스텀 시리얼 라이저를 작성하여 놀아본 후, 가장 간단한 해결책은 일반적인 래퍼라는 결론을 내 렸습니다. 당신이 상관 없어

@JsonRootName(value = "message") 
public class Message { ...} 

다음
new ObjectMapper().configure(SerializationFeature.WRAP_ROOT_VALUE, true).writeValueAs...

0

그것을 할 수있는 간단한/더 나은 방법 : 다음은 아마도 위의 예보다 간단한 구현입니다 json의 자본이 m 인 경우 message이면 가장 간단한 방법은 수업에 @JsonTypeInfo으로 주석을 추가하는 것입니다.

당신은 추가합니다 :

@JsonTypeInfo(include=As.WRAPPER_OBJECT, use=Id.NAME)` 
public class Message { 
    // ... 
} 

{"Message":{"text":"Text"}}

2

제공을 사용

public final class JsonObjectWrapper { 
    private JsonObjectWrapper() {} 

    public static <E> Map<String, E> withLabel(String label, E wrappedObject) { 
     HashMap<String, E> map = new HashMap<String, E>(); 
     map.put(label, wrappedObject); 
     return map; 
    } 
} 
0

를 얻기 위해 다음 application.properties 파일 추가에 다음, 스프링을 사용하는 경우 : -

spring.jackson.serialization.WRAP_ROOT_VALUE = 사실

그리고 직렬화하려는 클래스에 @JsonRootName 주석을 사용하십시오. 예 : json으로 문자열의 루트 요소의 이름은 잭슨, 직렬화시에 무시하는 않는 경우

@JsonRootName("user") 
public class User { 
    private String name; 
    private Integer age; 
}