2012-05-29 43 views
10

Tôi đã lớp sau:Force Jackson để thêm gói addional sử dụng chú thích

public class Message { 
    private String text; 

    public String getText() { 
     return text; 
    } 

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

Khi chuyển đổi các ví dụ để JSON sử dụng Jackson theo mặc định tôi nhận được:

{"text":"Text"} 

Tôi muốn nhận được:

{"message":{"text":"Text"}} 

Có chú thích JAXB/Jackson nào tôi có thể sử dụng để đạt được mục tiêu của mình không?

Là một workaround, tôi có thể bọc lớp học của tôi với một lớp khác:

public class MessageWrapper { 
    private Message message; 

    public Message getMessage() { 
     return message; 
    } 

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

hoặc một giải pháp chung chung hơn:

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); 
    } 
} 

Mà có thể được sử dụng như sau:

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

Có chú thích JAXB/Jackson nào tôi có thể sử dụng để đạt được không Mục tiêu của tôi?

Cảm ơn.

Trả lời

12

On workaround: bạn không hoàn toàn cần những getters/setters, vì vậy chỉ có thể có:

public class MessageWrapper { 
    public Message message; 
} 

hoặc có lẽ thêm constructor tiện theo dõi:

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

Có một cách để thêm gói quá; với 1.9 bạn có thể sử dụng SerializationConfig.Feature.WRAP_ROOT_ELEMENTDeserializationConfig.Feature.UNWRAP_ROOT_ELEMENT. Và nếu bạn muốn thay đổi tên wrapper (theo mặc định nó chỉ đơn giản là tên lớp không đủ tiêu chuẩn), bạn có thể sử dụng @JsonRootName chú thích

Jackson 2.0 bổ sung thêm tùy chọn thêm động thông qua ObjectReaderObjectWriter, cũng như JAX-RS chú thích.

+0

StaxMan, nếu tên phần tử gốc của Json Chuỗi phải được bỏ qua trong quá trình tuần tự, không Jackson 1.9 đòi hỏi chúng ta để thiết lập các tính năng 'DeserializationConfig.Feature.UNWRAP_ROOT_ELEMENT' một mình hoặc việc bổ sung các chú thích' @JsonRootName 'cũng được yêu cầu? – asgs

+1

Tôi phải xác minh - UNWRAP có thể là đủ; câu hỏi là liệu tên có phải là bản đồ hay không. Nhưng ngay cả khi không có '@ JsonRootName', tên mặc định tồn tại (tên lớp đơn giản), có thể hoạt động tốt. – StaxMan

+0

nó đã hoạt động! cảm ơn rất nhiều. – asgs

4

Thật buồn khi biết rằng bạn phải viết serialization tùy chỉnh cho mục tiêu đơn giản là gói một lớp với một đối tượng được gắn nhãn. Sau khi chơi xung quanh bằng cách viết một serializer tùy chỉnh, tôi kết luận rằng giải pháp đơn giản nhất là một wrapper chung. Đây là có lẽ là một thực hiện đơn giản hơn ví dụ của bạn ở trên:

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

A/Cách tốt hơn đơn giản để làm điều đó:

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

sau đó sử dụng
new ObjectMapper().configure(SerializationFeature.WRAP_ROOT_VALUE, true).writeValueAs...

2

Miễn là bạn không nhớ các json có số vốn là m trong message, thì cách đơn giản nhất để làm điều này là chú thích lớp học của bạn với @JsonTypeInfo.

Bạn sẽ thêm:

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

để có được {"Message":{"text":"Text"}}

0

Nếu sử dụng lò xo, sau đó trong application.properties tập tin add sau: -

spring.jackson.serialization.WRAP_ROOT_VALUE = true

Và sau đó sử dụng chú thích @JsonRootName trên bất kỳ lớp nào của bạn mà bạn muốn sắp xếp theo thứ tự. ví dụ.

@JsonRootName("user") 
public class User { 
    private String name; 
    private Integer age; 
} 
Các vấn đề liên quan