I\'m trying to read a legacy JSON code using Jackson 2.0-RC3, however I\'m stuck with an \"embedded\" object.
Given a following JSON:
{
\"title\"
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB 2 (JSR-222) expert group.
I'm not sure if Jackson supports this use case, but below is an example of how you can leverage MOXy's @XmlPath
extension to meet your requirements. Note you will need to use an EclipseLink 2.4.0 nightly label from April 7, 2012 or newer.
Item
The author
property on Item
is mapped with @XmlPath('.')
. This means that the content of Author
is pulled up to the same level as the content for Item
. I also needed to use an XmlAdapter
for the Date
property as the format you are using doesn't match MOXy's default representation.
package forum10036530;
import java.util.Date;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.eclipse.persistence.oxm.annotations.XmlPath;
@XmlAccessorType(XmlAccessType.FIELD)
class Item {
private String title;
@XmlElement(name="date")
@XmlJavaTypeAdapter(DateAdapter.class)
private Date createdAt;
@XmlPath(".")
private Author author;
}
Author
package forum10036530;
import java.net.URL;
import javax.xml.bind.annotation.*;
@XmlAccessorType(XmlAccessType.FIELD)
class Author {
@XmlElement(name="author")
private String name;
@XmlElement(name="author_avatar")
private URL avatar;
@XmlElement(name="author_group")
private Integer group;
@XmlElement(name="author_prop")
private String prop;
}
DateAdapter
package forum10036530;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class DateAdapter extends XmlAdapter<String, Date> {
private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
@Override
public Date unmarshal(String string) throws Exception {
return dateFormat.parse(string);
}
@Override
public String marshal(Date date) throws Exception {
return dateFormat.format(date);
}
}
jaxb.properties
A file called jaxb.properties
with the following entry must be placed in the same package as the domain classes to specify MOXy as the JAXB (JSR-222) provider.
javax.xml.bind.context.factory = org.eclipse.persistence.jaxb.JAXBContextFactory
input.json/Output
{
"title" : "Hello world!",
"date" : "2012-02-02 12:23:34",
"author" : "username",
"author_avatar" : "http://www.example.com/foo.png",
"author_group" : 123,
"author_prop" : "value"
}
For More Information
I would deserialize the original JSON to a single, flat object first (kind of like an adapter), then create your own domain objects.
class ItemLegacy {
private String title;
@JsonProperty("date")
private Date createdAt;
@JsonPropery("author")
private String name;
@JsonPropery("author_avatar")
private URL avatar;
@JsonProperty("author_group")
private Integer group;
@JsonProperty("author_prop")
private Integer group;
}
Then use this object to fill out your Item and Author objects and create the correct relationships.
//... the deserialized original JSON
ItemLegacy legacy ...
// create an author
Author author = new Author();
author.setName(legacy.getName());
author.setGroup(legacy.getGroup());
...
// create an item
Item item = new Item();
item.setTitle(legacy.getTitle());
...
// finally set the author... and you should have the desired structure
item.setAuthor(author);
Your Item
class could only be automatically deserialized from the following form:
{
"title": "Hello world!",
"date": "2012-02-02 12:23:34".
"author": {
"name": "username",
"author_avatar": "http://...",
"author_group": "123",
"author_prop": "value"
}
}
You might be able to do something with custom deserialization, but it would not be the simpler solution for sure.
To deal with an "embedded" object you should use @JsonUnwrapped
— it's an equivalent of the Hibernate's @Embeddable
/@Embedded
.
class Item {
private String title;
@JsonProperty("date")
private Date createdAt;
// How to map this?
@JsonUnwrapped
private Author author;
}