Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force Jackson to add addional wrapping using annotations

Tags:

I have the following class:

public class Message {
    private String text;

    public String getText() {
        return text;
    }

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

When converting the instance to JSON using Jackson by default I get:

{"text":"Text"}

I would like to get:

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

Is there any JAXB / Jackson annotation I can use to achieve my goal?

As a workaround, I can wrap my class with another class:

public class MessageWrapper {
    private Message message;

    public Message getMessage() {
        return message;
    }

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

or a more generic solution:

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

Which can be used like so:

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

Is there any JAXB / Jackson annotation I can use to achieve my goal?

Thanks.

like image 856
MosheElisha Avatar asked May 29 '12 08:05

MosheElisha


People also ask

What is JsonProperty annotation?

@JsonProperty is used to mark non-standard getter/setter method to be used with respect to json property.

What is the use of Jackson annotations?

This annotation is used to specify a custom deserializer in order to unmarshall a JSON object. Using this annotation, we use a default value for deserializing an unknown enum value. Using this annotation, you can mark a property or a group of properties to be ignored. This is done at the class level.

What does JsonUnwrapped do?

@JsonUnwrapped is used to unwrap values of objects during serialization or de-serialization.

What is the use of @JsonSerialize?

@JsonSerialize is used to specify custom serializer to marshall the json object.


2 Answers

With Jackson 2.x use can use the following to enable wrapper without adding addition properties in the ObjectMapper

import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeName;

@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME)
@JsonTypeName(value = "student")
public class Student {
  private String name;
  private String id;
}
like image 56
Raunaque Srivastava Avatar answered Oct 21 '22 17:10

Raunaque Srivastava


On workaround: you don't absolutely need those getters/setters, so could just have:

public class MessageWrapper {
  public Message message;
}

or perhaps add convenience constructor:

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

There is a way to add wrapping too; with 1.9 you can use SerializationConfig.Feature.WRAP_ROOT_ELEMENT and DeserializationConfig.Feature.UNWRAP_ROOT_ELEMENT. And if you want to change the wrapper name (by default it is simply unqualified class name), you can use @JsonRootName annotation

Jackson 2.0 adds further dynamic options via ObjectReader and ObjectWriter, as well as JAX-RS annotations.

like image 32
StaxMan Avatar answered Oct 21 '22 15:10

StaxMan