2012-04-05 33 views
9

Tôi đang cố gắng đọc mã JSON cũ bằng cách sử dụng Jackson 2.0-RC3, tuy nhiên tôi bị kẹt với đối tượng "được nhúng".Đọc đối tượng nhúng trong Jackson

Cho một JSON sau:

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

Làm thế nào tôi có thể ánh xạ nó vào cấu trúc sau:

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

Tôi đã cố gắng để làm điều đó với @JsonDeserialize nhưng có vẻ như tôi sẽ phải ánh xạ toàn bộ đối tượng Item theo cách đó.

Trả lời

24

Để đối phó với một đối tượng "nhúng" bạn nên sử dụng @JsonUnwrapped - đó là một tương đương của Hibernate @Embeddable/@Embedded.

class Item { 
    private String title; 

    @JsonProperty("date") 
    private Date createdAt; 

    // How to map this? 
    @JsonUnwrapped 
    private Author author; 
} 
1

Tôi sẽ deserialize JSON gốc thành một đối tượng phẳng đơn đầu tiên (giống như một bộ điều hợp), sau đó tạo các đối tượng miền của riêng bạn.

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

Sau đó, sử dụng đối tượng này để điền đối tượng Mục và Tác giả và tạo mối quan hệ chính xác.

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

bạnItem lớp chỉ có thể được tự động deserialized từ các hình thức sau đây:

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

Bạn có thể có thể làm điều gì đó với deserialization tùy chỉnh, nhưng nó sẽ không phải là giải pháp đơn giản chắc chắn.

+0

Tôi không cần phải tuần tự hóa đúng JSON. Tất cả những gì tôi cần là ** deserialize ** từ JSON kế thừa thành các đối tượng được định dạng tốt. – Crozin

+0

Tôi hy vọng các chỉnh sửa của tôi làm rõ rằng tôi đã không nói về serialization ... –

+0

Oh, bây giờ tôi nhận được nó. Tôi đã hy vọng rằng Jackson cung cấp tương đương với '@ Embeddable' /' @ Embedded' của Hibernate. – Crozin

0

Lưu ý: Tôi là người dẫn đầu EclipseLink JAXB (MOXy) và là thành viên của nhóm JAXB 2 (JSR-222) chuyên gia.

Tôi không chắc liệu Jackson có hỗ trợ trường hợp sử dụng này hay không, nhưng dưới đây là ví dụ về cách bạn có thể tận dụng tiện ích mở rộng củacủa MOXy để đáp ứng các yêu cầu của bạn. Lưu ý rằng bạn sẽ cần sử dụng nhãn hàng đêm EclipseLink 2,4.0 từ ngày 7 tháng 4 năm 2012 trở lên.

mục

Các tài sản trên Itemauthor được ánh xạ với @XmlPath('.'). Điều này có nghĩa là nội dung của Author được kéo lên cùng cấp với nội dung cho Item. Tôi cũng cần sử dụng một số XmlAdapter cho thuộc tính Date vì định dạng bạn đang sử dụng không khớp với biểu diễn mặc định của 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; 
} 

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.các thuộc tính

Tệp có tên jaxb.properties với mục sau phải được đặt trong cùng một gói với các lớp miền để chỉ định MOXy làm nhà cung cấp JAXB (JSR-222).

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

input.json/Output

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

Để biết thêm thông tin

+1

Tôi chưa thử nghiệm, nhưng đây chính xác là những gì tôi đang tìm kiếm. – Crozin

+0

@Crozin - Tôi phải đưa vào một bản sửa lỗi để xử lý thuộc tính URL để ví dụ hoàn chỉnh sẽ yêu cầu xây dựng phần cứng, nhưng mọi thứ khác đều hoạt động với bản dựng hiện tại. –

Các vấn đề liên quan