阅读Jackson中的嵌入对象

时间:2012-04-05 21:50:09

标签: java json mapping 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对象。

3 个答案:

答案 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"
}

了解更多信息