Проблема с сортировкой JAXB XMLAdapter
У меня есть требование для генерации XML
файл с форматом ниже, используя JAXB2
, Он имеет как фиксированный, так и переменный контент XML.
Что такое ограничение?
Содержание переменной XML
Часть должна быть одной из 5 разных XML schema
(планируется иметь JAXB2.0
реализовал 5 различных классов Java для его генерации), который должен быть встроен в фиксированный XML
содержание.
Формат XML:
<user_info>
<header> //Fixed XML Part
<msg_id>..</msg_id>
<type>...</type>
</header>
<user_type> // Variable XML content
// (userType : admin, reviewer, auditer, enduser, reporter)
........
</user_type>
</user_info>
Что я пробовал?
Я создал JAXB
аннотированные классы Java для вышеупомянутого XML metadata
, Для переменной XML-части я использовал общий родительский класс (BaseUserType
) который был расширен на все 5 разных классов <user_type>
, И пытался переопределить marshall(..)
операция с использованием @XmlJavaTypeAdapter
, (как показано ниже)
JAXB Аннотированный класс:
@XmlRootElement(name="user_info")
public class UserInfo {
private Header header; //reference to JAXB annotated Class Header.class
@XmlJavaTypeAdapter(value=CustomXMLAdapter.class)
private BaseUserType userType; // Base class - acts as a common Type
// for all 5 different UserType JAXB annotated Classes
// Getters setters here..
// Also tried to declare JAXB annotations at Getter method
}
Пользовательский класс адаптера XML:
public class CustomXMLAdapter extends XmlAdapter<Writer, BaseInfo> {
private Marshaller marshaller=null;
@Override
public BaseInfo unmarshal(Writer v) throws Exception {
// Some Implementations here...
}
@Override
public Writer marshal(BaseInfo v) throws Exception {
OutputStream outStream = new ByteArrayOutputStream();
Writer strResult = new OutputStreamWriter(outStream);
if(v instanceof CustomerProfileRequest){
getMarshaller().marshal((CustomerProfileRequest)v, strResult );
}
return strResult;
}
private Marshaller getMarshaller() throws JAXBException{
if(marshaller==null){
JAXBContext jaxbContext = JAXBContext.newInstance(Admin.class, Reviewer.class, Enduser.class, Auditor.class, Reporter.class);
marshaller = jaxbContext.createMarshaller();
}
return marshaller;
}
}
Где я сейчас борюсь?
Я не сталкиваюсь ни с какими ошибками или предупреждениями, XML
генерируется (как показано ниже). Но результат не является ожидаемым. Он не встраивает переменную часть XML с фиксированной правильно.
Выход
<user_info>
<header>
<msg_id>100</msg_id>
<type>Static</type>
</header>
<user_type/> // Empty Element, even though we binded the value properly.
</user_info>
Мои вопросы:
- Почему
JAXB marshallers
не мог встроитьCustomXMLAdapter
"упорядочить содержание с родительским(UserInfo.class)
, - Есть ли у нас какой- либо альтернативный вариант в
JAXB
сделать это просто? - Как указать
BoundType
,ValueType
вXMLAdapter
, Есть ли какой-то конкретный тип, который нужно указать для встраивания контента в маршаллинг родительского класса?
1 ответ
XmlAdapter
работает, позволяя вам конвертировать из вашего доменного объекта в другой объект значения, который JAXB может лучше обрабатывать для целей Marshalling / Unmarshalling.
Если все объекты модели из других схем действительно являются подклассами BaseUserType
тогда все, что вам нужно сделать, это сделать JAXBContext
знать о них. Вы можете сделать это при создании JAXBContext
разделив двоеточие String со всеми именами пакетов.
JAXBContext jc = JAXBContext.newInstance("com.example.common:com.example.foo:com.example.bar");