2013-01-08 21 views
10

Tôi đã có một lớp mẫu:EclipseLink MOXY JSON serialization

class Zoo { 
    public Collection<? extends Animal> animals; 
} 

Khi serialized với MOXY, tôi nhận được:

{ 
    "bird": [ 
     { 
      "name": "bird-1", 
      "wingSpan": "6 feets", 
      "preferredFood": "food-1" 
     } 
    ], 
    "cat": [ 
     { 
      "name": "cat-1", 
      "favoriteToy": "toy-1" 
     } 
    ], 
    "dog": [ 
     { 
      "name": "dog-1", 
      "breed": "bread-1", 
      "leashColor": "black" 
     } 
    ] 
} 

Tại sao nó sử dụng các chỉ số mảng "[]", trong khi chim , mèo và chó không phải là mảng? Thứ hai, có cách nào để loại bỏ "chim", "mèo" và "chó" không?

Nói cách khác, tôi đang cố gắng để có được:

{ 
     { 
      "name": "bird-1", 
      "wingSpan": "6 feets", 
      "preferredFood": "food-1" 
     } 
    , 
     { 
      "name": "cat-1", 
      "favoriteToy": "toy-1" 
     } 
    , 
     { 
      "name": "dog-1", 
      "breed": "bread-1", 
      "leashColor": "black" 
     } 
} 

Cảm ơn, Behzad

Trả lời

9

CÂU HỎI # 1

Tại sao nó sử dụng các chỉ số mảng "[] ", trong khi chim, mèo và chó là không phải mảng?

Để có được biểu diễn JSON này, bạn đã ánh xạ mô hình của mình bằng chú thích @XmlElementRef để cho JAXB sử dụng giá trị của chú thích @XmlRootElement làm chỉ báo kế thừa. Với JSON của MOX ràng buộc chúng trở thành chìa khóa. Chúng tôi làm cho giá trị của các khóa này là các mảng JSON vì các khóa không được phép lặp lại.

Zoo

Trong mô hình của bạn, bạn có @XmlElementRef chú thích trên animals lĩnh vực của bạn/tài sản.

import java.util.Collection; 
import javax.xml.bind.annotation.XmlElementRef; 

class Zoo { 
    @XmlElementRef 
    public Collection<? extends Animal> animals; 
} 

Animal

import javax.xml.bind.annotation.*; 

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlSeeAlso({Bird.class, Cat.class, Dog.class}) 
public abstract class Animal { 

    private String name; 

} 

Bird

Trên mỗi lớp con của bạn, bạn có một chú thích @XmlRootElement.

import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
public class Bird extends Animal { 

    private String wingSpan; 
    private String preferredFood; 

} 

input.json/Output

{ 
    "bird" : [ { 
     "name" : "bird-1", 
     "wingSpan" : "6 feets", 
     "preferredFood" : "food-1" 
    } ], 
    "cat" : [ { 
     "name" : "cat-1", 
     "favoriteToy" : "toy-1" 
    } ], 
    "dog" : [ { 
     "name" : "dog-1", 
     "breed" : "bread-1", 
     "leashColor" : "black" 
    } ] 
} 

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


CÂU HỎI # 2

Thứ hai, là có một cách để thoát khỏi "con chim", "mèo", và "con chó"?

Bạn sẽ cần một số loại chỉ báo kế thừa để đại diện cho các lớp con khác nhau.

OPTION # 1 - @XmlDescriminatorNode/@XmlDescriminatorValue

Ở đây tôi làm @XmlDescriminatorNode/@XmlDescriminatorValue chú thích này bằng MOXY của.

Zoo

import java.util.Collection; 

class Zoo { 
    public Collection<? extends Animal> animals; 
} 

Animal

import javax.xml.bind.annotation.*; 
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorNode; 

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlSeeAlso({Bird.class, Cat.class, Dog.class}) 
@XmlDiscriminatorNode("@type") 
public abstract class Animal { 

    private String name; 

} 

Bird

import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue; 

@XmlDiscriminatorValue("bird") 
public class Bird extends Animal { 

    private String wingSpan; 
    private String preferredFood; 

} 

input.json/Output

{ 
    "animals" : [ { 
     "type" : "bird", 
     "name" : "bird-1", 
     "wingSpan" : "6 feets", 
     "preferredFood" : "food-1" 
    }, { 
     "type" : "cat", 
     "name" : "cat-1", 
     "favoriteToy" : "toy-1" 
    }, { 
     "type" : "dog", 
     "name" : "dog-1", 
     "breed" : "bread-1", 
     "leashColor" : "black" 
    } ] 
} 

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

OPTION # 2 - @XmlClassExtractor

ClassExtractor (AnimalExtractor)

Bạn có thể viết một số mã để xác định phân lớp phù hợp dựa trên nội dung JSON.

import org.eclipse.persistence.descriptors.ClassExtractor; 
import org.eclipse.persistence.sessions.*; 

public class AnimalExtractor extends ClassExtractor { 

    @Override 
    public Class extractClassFromRow(Record record, Session session) { 
     if(null != record.get("@wingSpan") || null != record.get("@preferredFood")) { 
      return Bird.class; 
     } else if(null != record.get("@favoriteToy")) { 
      return Cat.class; 
     } else { 
      return Dog.class; 
     } 
    } 

} 

Animal

Các @XmlClassExtractor chú thích được sử dụng để xác định ClassExtractor.

import javax.xml.bind.annotation.*; 
import org.eclipse.persistence.oxm.annotations.XmlClassExtractor; 

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlSeeAlso({Bird.class, Cat.class, Dog.class}) 
@XmlClassExtractor(AnimalExtractor.class) 
public abstract class Animal { 

    private String name; 

} 

Bird

Do cách MOXY xử lý @XmlElement@XmlAttribute chú thích, bất kỳ dữ liệu bạn muốn được cung cấp cho các ClassExtractor sẽ cần phải được chú thích với @XmlAttribute.

import javax.xml.bind.annotation.XmlAttribute; 

public class Bird extends Animal { 

    @XmlAttribute 
    private String wingSpan; 

    @XmlAttribute 
    private String preferredFood; 

} 

đầu vào.json/Output

{ 
    "animals" : [ { 
     "wingSpan" : "6 feets", 
     "preferredFood" : "food-1", 
     "name" : "bird-1" 
    }, { 
     "favoriteToy" : "toy-1", 
     "name" : "cat-1" 
    }, { 
     "breed" : "bread-1", 
     "leashColor" : "black", 
     "name" : "dog-1" 
    } ] 
} 

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


DEMO MÃ

Mã trình diễn sau có thể được sử dụng với cả hai ánh xạ được mô tả ở trên.

import java.util.*; 
import javax.xml.bind.*; 
import javax.xml.transform.stream.StreamSource; 
import org.eclipse.persistence.jaxb.JAXBContextProperties; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     Map<String, Object> properties = new HashMap<String, Object>(); 
     properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json"); 
     properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false); 
     JAXBContext jc = JAXBContext.newInstance(new Class[] {Zoo.class}, properties); 

     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     StreamSource json = new StreamSource("src/forum14210676/input.json"); 
     Zoo zoo = unmarshaller.unmarshal(json, Zoo.class).getValue(); 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(zoo, System.out); 
    } 

} 
+1

Cảm ơn U rất nhiều vì phản hồi của bạn. –

+0

Cảm ơn bạn rất nhiều vì đã trả lời. Tôi nhận được một ngoại lệ trong quá trình de-serialization. Tôi không thể cập nhật bài đăng. Tôi đã thêm thông tin này làm câu trả lời. Cảm ơn bạn đã giúp đỡ! –

+0

@BehzadPirvali - Bạn có thể đăng vấn đề bạn đang xem dưới dạng câu hỏi mới không? –