В настоящее время я разрабатываю общий формат обмена сообщениями для связи клиент-сервер.В сообщении есть поле, которое будет переопределено каждым конкретным веб-сервисом.Ниже приведен упрощенный пример:
class Message {
public BasicInfo basicInfo;
}
BasicInfo
- базовый класс.Все производные классы не будут иметь открытого конструктора без аргументов.Поэтому я написал XmlAdapter
для них.
@XmlJavaTypeAdapter(...)
class SpecificInfoA extends BasicInfo {
// Detail omitted
}
Затем я обновил класс Message
, надеясь, что jaxb сможет определить класс во время выполнения и использовать соответствующий адаптер для преобразования объекта ...
@XmlRootElement
@XmlSeeAlso({SpecificInfoA.class})
class Message {
@XmlAnyElement
public BasicInfo basicInfo;
}
Но когда я создаю JAXBContext
:
JAXBContext context = JAXBContext.newInstance(Message.class);
Выдается исключение:
com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
playground.SpecificInfoA does not have a no-arg default constructor.
this problem is related to the following location:
at playground.SpecificInfoA
at @javax.xml.bind.annotation.XmlSeeAlso(value=[class playground.SpecificInfoA])
at com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:106)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:466)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:298)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:141)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1157)
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:145)
Так как SpecificInfoA
имеет XmlAdapter
,Я ожидал, что jaxb сможет добавить его в свой контекст, но из вышеприведенного исключения это просто невозможно сделать, или я делаю это неправильно?
Я знаю, что могу написать общий XmlAdapter
дляBasicInfo
, который преобразует экземпляры в общий тип связывания при маршалинге и создает конкретные экземпляры обратно при демаршаллинге.Однако он будет тесно связывать все производные классы в один адаптер, что нежелательно.