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
và @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);
}
}
Cảm ơn U rất nhiều vì phản hồi của bạn. –
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 đỡ! –
@BehzadPirvali - Bạn có thể đăng vấn đề bạn đang xem dưới dạng câu hỏi mới không? –