jackson 주석을 사용하여 2 단계 다형성 하위 유형을 역 직렬화하고 싶습니다. 기본적으로 다음과 같이 json 주석과 잭슨을 사용하여 다음 json을 xml로 변환하고 싶습니다.
{
"mainSet": {
"name": "bla bla",
"myItems": [
{
"MySubItem": {
"id": 1,
"name": "Value1",
"itemAProperty1": "Some stuff",
"itemAProperty2": "Another property value",
"type": "MySubItemA"
}
},
{
"MySubItem": {
"id": 2,
"name": "Value2",
"itemBProperty1": 1000,
"itemBProperty2": "B property",
"type": "MySubItemB"
}
}
]
}
}
그리고 내가 원하는 최종 Xml은
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<mainTag schemaVersion="1" xmlns="http://www.utiba.com/xml/ns/brms/v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<name>bla bla</name>
<MySubItem xsi:type="MySubItemA" id="1" name="value1" itemAProperty1="Some stuff" itemAProperty2="Another property value"/>
<MySubItem xsi:type="MySubItemB" id="2" name="value2" itemAProperty1=1000 itemAProperty2="B Property"/>
</mainTag>
다음 클래스 세트가 있습니다-메인 클래스
public abstract class MyItem {
private int id;
private String name;
//getter and setter
}
추상 하위 클래스가
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "MySubItem")
@XmlSeeAlso({
MySubItemA.class,
MySubItemB.class,
MySubItemC.class
})
public abstract class MySubItem extends MyItem {
private String itemAProperty1;
private String itemAProperty2;
//getter and setter
}
MySubItem에는 MySubItemA, MySubItemB, MySubItemC라는 구체적인 하위 클래스가 있습니다.
이제 마지막으로 추상 클래스의 객체 목록을 포함하는 클라이언트 클래스를 만듭니다.
import java.util.ArrayList;
import java.util.List;
public class MainSet{
@XmlElements({
@XmlElement(name = "MysubItem", type = MySubItem.class),
})
private List<MyItem> myItems;
public List<MyItem> getMyItems() {
return this.myItems;
}
}
MyItem에 대한 Mixin 클래스를 만들려고했습니다.
@JsonTypeInfo(use=Id.MINIMAL_CLASS, include=As.PROPERTY, property="itemType")
@JsonSubTypes({
@Type(MySubItem.class)
})
및 MySubItem
@JsonTypeInfo(use=Id.MINIMAL_CLASS, include=As.PROPERTY, property="type")
@JsonSubTypes({
@Type(MySubItemA.class)
@Type(MySubItemB.class)
@Type(MySubItemC.class)
})
내가 얻는 오류는 다음과 같습니다.
Error parsing JSON from client: com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of MySubItem, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information
at [Source: java.io.StringReader@26bd8952; line: 1, column: 498] (through reference chain: bla bla class ["mainSet"]->com.bla.bla["myItems"])
문제 : 2 단계의 추상 하위 클래스 계층 구조를 갖는 myItems 목록에 대한 mixin 클래스 생성
여러 수준의 다형성 유형 계층 구조는 Jackson API에서 지원하지 않습니다.
https://github.com/FasterXML/jackson-databind/issues/374 에서 볼 수 있습니다.
따라서해야 할 일은 다음과 같습니다.
Deserializer (MySubItem.class의 경우 MySubItemDeserializerMixin.class라고 함)를 만들고 다른 Mixin 클래스와 마찬가지로 jsonMapper로 구성하십시오.
mapper.addMixInAnnotations(MySubItem.class, MySubItemDeserializerMixin.class);
MySubItemDeserializerMixin.java는 다음과 같습니다.
@JsonDeserialize(using = MySubItemDeserializer.class)
public abstract class MySubItemDeserializerMixin{
}
또한 MySubItemDeserializerMixin.java에 지정된대로 MySubItem에 대한 deserializer (MySubItemDeserializer)를 만들어야합니다.
이제 다음과 같은 MySubItemMixin.java를 만들어야합니다.
@JsonTypeInfo(use=Id.MINIMAL_CLASS, include=As.PROPERTY, property="type")
@JsonSubTypes({
@Type(MySubItemA.class)
@Type(MySubItemB.class)
@Type(MySubItemC.class)
})
MySubItemDeserializer에서 다음과 같은 작업을 수행합니다.
@Override
public MySubItem deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
JsonNode node = jsonParser.getCodec().readTree(jsonParser);
ObjectMapper jsonMapper = new ObjectMapper();
// Omit null values from the JSON.
jsonMapper.setSerializationInclusion(Include.NON_NULL);
// Treat received empty JSON strings as null Java values.
// Note: doesn't seem to work - using custom deserializer through module
// below instead.
jsonMapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
jsonMapper.addMixInAnnotations(MySubItem.class, MySubItemMixin.class);
// Enable interpretation of JAXB annotations on our beans (e.g. for
// resolving ID/IDREF references).
jsonMapper.registerModule(new JaxbAnnotationModule());
MySubItem condition = jsonMapper.readValue(node.toString(), MySubItem.class);
}
귀하의 우려가 해결되기를 바랍니다.
감사합니다.
나쿨 바쉬 쉬스
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다