阅读Jackson中的嵌入对象

我正在尝试使用Jackson 2.0-RC3读取遗留的JSON代码,但是我坚持使用“嵌入式”对象。

给出以下JSON:

{ "title": "Hello world!", "date": "2012-02-02 12:23:34". "author": "username", "author_avatar": "http://.../", "author_group": 123, "author_prop": "value" } 

如何将其映射到以下结构中:

 class Author { @JsonPropery("author") private String name; @JsonPropery("author_avatar") private URL avatar; @JsonProperty("author_group") private Integer group; ... } class Item { private String title; @JsonProperty("date") private Date createdAt; // How to map this? private Author author; } 

我试图用@JsonDeserialize做到这一点,但似乎我必须以这种方式映射整个Item对象。

要处理“嵌入”对象,你应该使用@JsonUnwrapped – 它相当于Hibernate的@Embeddable / @Embedded

 class Item { private String title; @JsonProperty("date") private Date createdAt; // How to map this? @JsonUnwrapped private Author author; } 

我首先将原始JSON反序列化为单个扁平对象(有点像适配器),然后创建自己的域对象。

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

然后使用此对象填写Item和Author对象并创建正确的关系。

  //... 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); 

您的 Item只能从以下格式自动反序列化:

 { "title": "Hello world!", "date": "2012-02-02 12:23:34". "author": { "name": "username", "author_avatar": "http://...", "author_group": "123", "author_prop": "value" } } 

您可以使用自定义反序列化来执行某些操作,但它肯定不是更简单的解决方案。

注意:我是EclipseLink JAXB(MOXy)的负责人,也是JAXB 2(JSR-222)专家组的成员。

我不确定Jackson是否支持此用例,但下面是如何利用MOXy的@XmlPath扩展来满足您的要求的@XmlPath 。 请注意,您需要使用2012年4月7日或更新版本的EclipseLink 2.4.0夜间标签。

项目

Item上的author属性与@XmlPath('.')映射。 这意味着Author的内容被拉到与Item的内容相同的级别。 我还需要为Date属性使用XmlAdapter ,因为您使用的格式与MOXy的默认表示不匹配。

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

作者

 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 { 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

具有以下条目的名为jaxb.properties的文件必须与域类放在同一个包中,以将MOXy指定为JAXB(JSR-222)提供程序。

 javax.xml.bind.context.factory = org.eclipse.persistence.jaxb.JAXBContextFactory 

input.json /输出

 { "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" } 

了解更多信息