2012-04-05 72 views
9

我想讀取使用傑克遜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對象。

回答

24

爲了應對「嵌入」的對象,你應該使用@JsonUnwrapped - 這是Hibernate的@Embeddable/@Embedded的等效。

class Item { 
    private String title; 

    @JsonProperty("date") 
    private Date createdAt; 

    // How to map this? 
    @JsonUnwrapped 
    private Author author; 
} 
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" 
       } 
} 

你也許能夠做定製反序列化的東西,但它不會是簡單的解決方案當然。

+0

我不需要序列化到正確的JSON。我需要的只是**從傳統的JSON反序列化成格式良好的對象。 – Crozin 2012-04-05 23:53:12

+0

我希望我的編輯能夠澄清我不是在談論序列化... – 2012-04-06 00:36:39

+0

哦,現在我明白了。我希望Jackson提供了一個相當於Hibernate的'@ Embeddable' /'@ Embedded'。 – Crozin 2012-04-06 00:51:15

0

注:我是EclipseLink JAXB (MOXy)鉛和JAXB 2 (JSR-222)專家小組的成員。

我不確定傑克遜是否支持此用例,但下面是如何利用MOXy的@XmlPath擴展來滿足您的需求的示例。請注意,您需要使用2012年4月7日或更新的EclipseLink 2.4.0夜間標籤。

項目

Itemauthor屬性映射與@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。屬性

具有以下條目的名爲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" 
} 

更多信息

+1

我還沒有測試過,但這正是我所期待的。 – Crozin 2012-04-06 20:40:28

+0

@Crozin - 我必須修復以處理URL屬性,因此完整的示例將需要構建tonights,但其他所有內容都適用於當前構建。 – 2012-04-06 20:42:09