阅读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" }
了解更多信息