我正在尝试使用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
对象。
答案 0 :(得分:37)
要处理“嵌入”对象,您应该使用@JsonUnwrapped
- 它等同于Hibernate的@Embeddable
/ @Embedded
。
class Item {
private String title;
@JsonProperty("date")
private Date createdAt;
// How to map this?
@JsonUnwrapped
private Author author;
}
答案 1 :(得分:1)
我首先将原始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"
}
}
您可以使用自定义反序列化来执行某些操作,但它肯定不是更简单的解决方案。
答案 2 :(得分:0)
注意:我是EclipseLink JAXB (MOXy)主管,是JAXB 2 (JSR-222)专家组的成员。
我不确定Jackson是否支持此用例,但下面是如何利用MOXy的@XmlPath
扩展来满足您的要求的示例。请注意,您需要使用2012年4月7日或更新版本的EclipseLink 2.4.0夜间标签。
<强>物品强>
author
上的Item
属性与@XmlPath('.')
对齐。这意味着Author
的内容会提升到与Item
的内容相同的水平。我还需要对XmlAdapter
属性使用Date
,因为您使用的格式与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<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 强>
具有以下条目的名为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"
}
了解更多信息