Java JaxB - объект для XML-строки для объекта
У меня проблема с JaxB в Netbeans 7.1.2.
У меня есть автогенерированные мои классы из схемы с использованием JaxB (New JaxB Binding). Я создаю объект, который будет сериализован в строку XML, используя Marshaller, а затем обратно к экземпляру нового объекта из XML String. Однако я получаю следующее исключение:
javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.somewhere.com/some/path", local:"MyQueryComplexTypeQuery"). Expected elements are (none)
Строка marshalling/serializing to XML отлично работает. Это когда он не маршируется/десериализован, что вызывает проблему.
Я использую следующий код для создания объекта и его привязки к XML-строке:
// build the object
ObjectFactory of = new ObjectFactory();
MyQueryComplexType oaaqc = of.createMyQueryComplexType();
oaaqc.setField1("edit");
oaaqc.setField2("net");
oaaqc.setField3("24");
JAXBElement<MyQueryComplexType> createMyQueryComplexType = of.createMyQueryComplexTypeQuery(oaaqc);
// serialise to xml
StringWriter writer = new StringWriter();
JAXBContext context = JAXBContext.newInstance(MyQueryComplexType.class);
Marshaller m = context.createMarshaller();
m.marshal(createMyQueryComplexType, writer);
// output string to console
String theXML = writer.toString();
System.out.println(theXML);
В результате создается следующий XML (отформатированный) в консоли:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<MyQueryComplexTypeQuery xmlns="http://www.somewhere.com/some/path">
<Field1>edit</Field1>
<Field2>net</Field2>
<Field3>24</Field3>
</MyQueryComplexTypeQuery>
Теперь я пришел к десериализации/развязыванию строки к новому экземпляру MyQueryComplexType со следующим кодом:
Unmarshaller u = context.createUnmarshaller();
MyQueryComplexTypeQuery o = (MyQueryComplexType) u.unmarshal(new StringReader(theXML));
В автоматическом сгенерированном package-info.java он имеет следующее содержимое:
@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.somewhere.com/some/path", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package MyProject.SomeNamespace.MyQuery;
Я думал, что простой объект объекта → string → будет работать. Это первый раз, когда я использовал JaxB (так что будьте осторожны). Я видел другие сообщения, в которых упоминаются пространства имен, и все выглядит нормально для меня. Я автоматически сгенерировал классы из схемы, построил объект, упорядочил строку xml. Я думал, что просто обратный процесс для немаршала будет похож.
Фактическое исключение выбрано в строке:
MyQueryComplexTypeQuery o = (MyQueryComplexType) u.unmarshal(new StringReader(theXML));
Я думал, что я делаю unmarshalling из строки в объект, было бы просто. Я не знаю, что я делаю что-то неправильно или что-то не хватает. Надеюсь, вы, ребята, можете пролить свет или открыть глаза.
Я сократил код, чтобы упростить то, что в моем приложении вызывает ошибку. Пространства имен были изменены, чтобы защитить личность вещей в Интернете.
Любые мысли?
Спасибо
Andez
Ответы
Ответ 1
Создание JAXBContext
Для моделей JAXB, созданных из XML-схемы, вы можете создать JAXBContext
в имени пакета, а не в определенном классе:
JAXBContext context = JAXBContext.newInstance("your.package.name");
Не:
JAXBContext context = JAXBContext.newInstance(MyQueryComplexType.class);
Это гарантирует, что класс ObjectFactory
, содержащий аннотации @XmlElementDecl
, обрабатывается правильно, чего нет в вашем случае использования.
Работа с немаршалом
Обратите внимание, что во время операции маршала вам нужно было обернуть ваш экземпляр MyQueryComplexType
в JAXBElement
? Это связано с тем, что MyQueryComplexType
не был аннотирован с помощью @XmlRootElement
, а информация о корневом элементе должна была поступать из JAXBElement
. Это означает, что когда вы выполняете операцию unmarshal, вы также получите обратно JAXBElement
.
JAXBElement<MyQueryComplexTypeQuery> o = (JAXBElement<MyQueryComplexType>) u.unmarshal(new StringReader(theXML));
Не:
MyQueryComplexTypeQuery o = (MyQueryComplexType) u.unmarshal(new StringReader(theXML));
Дополнительная информация