I need to configure Jackson in a specific way which I'll describe below.
Requirements
- Annotated fields are serialized with only their id:
- If the field is a normal object, serialize its
id
- If the field is a collection of objects, serialize an array of
id
- If the field is a normal object, serialize its
- Annotated fields get their property names serialized differently:
- If the field is a normal object, add
"_id"
suffix to property name - If the field is a collection of objects, add
"_ids"
suffix to property name
- If the field is a normal object, add
- For the annotation I was thinking something like a custom
@JsonId
, ideally with an optional value to override the name just like@JsonProperty
does - The id property should be defined by the user, either using:
- The already existing Jackson's
@JsonIdentityInfo
- Or by creating another class or field annotation
- Or by deciding which annotation to inspect for
id
property discoverability (useful for JPA scenarios, for example)
- The already existing Jackson's
- Objects should be serialized with a wrapped root value
- Camel case naming should be converted to lower case with underscores
- All of this should be deserializable (by constructing an instance with just the id setted)
An example
Considering these POJO's:
//Inform Jackson which property is the id
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id"
)
public abstract class BaseResource{
protected Long id;
//getters and setters
}
public class Resource extends BaseResource{
private String name;
@JsonId
private SubResource subResource;
@JsonId
private List<SubResource> subResources;
//getters and setters
}
public class SubResource extends BaseResource{
private String value;
//getters and setters
}
A possible serialization of a Resource
instance could be:
{
"resource":{
"id": 1,
"name": "bla",
"sub_resource_id": 2,
"sub_resource_ids": [
1,
2,
3
]
}
}
So far...
Requirement #5 can be accomplished by configuring
ObjectMapper
in the following way:objectMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true); objectMapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
And then using
@JsonRootName("example_root_name_here")
in my POJO's.Requirement #6 can be accomplished by configuring
ObjectMapper
in the following way:objectMapper.setPropertyNamingStrategy( PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
As you can see there are still lots of requirements to fulfill. For those wondering why I need such a configuration, it's because I'm developing a REST webservice for ember.js (more specifically Ember Data). You would appreciate very much if you could help with any of the requirements.
Thanks!