Как размонтировать SOAP XML-объект Java
при попытке развязать мой XML-мыло к объекту JAXB возникает следующая ошибка.
Мы получаем ошибку, которую ожидаемый элемент не имеет. Если что-то конкретное должно быть сделано при развязывании XML файла SOAP.
javax.xml.bind.JAXBContext jaxbContext = (javax.xml.bind.JAXBContext) JAXBContext.newInstance(Class.forName(requestName));
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
StringReader reader = new StringReader(SoapXmlString);
reqInfo = unmarshaller.unmarshal(reader);
Получается следующая ошибка:
javax.xml.bind.UnmarshalException: unexpected element (uri:"http://schemas.xmlsoap.org/soap/envelope/", local:"Envelope"). Expected elements are (none)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:642)
at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:254)
at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:249)
at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:116)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement
и вот пример XML
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v2="http://example.com/v2">
<soapenv:Header/>
<soapenv:Body>
<v2:createSession>
<v2:client>
<!--Optional:-->
<v2:name>?</v2:name>
<!--Optional:-->
<v2:clientId>?</v2:clientId>
<!--Optional:-->
<v2:requestId>?</v2:requestId>
</v2:client>
<!--Optional:-->
<v2:oldSessionId>?</v2:oldSessionId>
<!--Optional:-->
<v2:clientIp>?</v2:clientIp>
<!--Optional:-->
<v2:clientIpStatus>?</v2:clientIpStatus>
<!--Optional:-->
<v2:superBYOBFlow>?</v2:superBYOBFlow>
<!--Optional:-->
<v2:FlowParams>?</v2:FlowParams>
<!--Optional:-->
<v2:deviceInfo>?</v2:deviceInfo>
</v2:createSession>
</soapenv:Body>
</soapenv:Envelope>
Пожалуйста, помогите.
Ответы
Ответ 1
Я не думаю, что вы принимаете конверт SOAP... Ваш сгенерированный JAXB Unmarshaller ничего не узнает о тегах Body или Envelope, он будет ожидать, что ваш createSession станет корневым элементом, следовательно, неожиданный элемент ".
Сначала вы должны извлечь содержимое из Envelope, вы можете сделать это с помощью message.getSOAPBody(). extractContentAsDocument(), если сначала создать объект SOAPMessage из вашего контента.
Это довольно сложно сделать, вот рабочий пример из моего blog
String example =
"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"><soapenv:Header /><soapenv:Body><ns2:farm xmlns:ns2=\"http://adamish.com/example/farm\"><horse height=\"123\" name=\"glue factory\"/></ns2:farm></soapenv:Body></soapenv:Envelope>";
SOAPMessage message = MessageFactory.newInstance().createMessage(null,
new ByteArrayInputStream(example.getBytes()));
Unmarshaller unmarshaller = JAXBContext.newInstance(Farm.class).createUnmarshaller();
Farm farm = (Farm)unmarshaller.unmarshal(message.getSOAPBody().extractContentAsDocument());
Похоже, что если вы не объявите свое пространство имен в файле .xsd схемы, вы увидите имеющуюся у вас ошибку.
Я создал фиктивную схему с корневым элементом createSession и добавив атрибут targetNamespace и регенерируя классы JAXB, ошибка исчезла
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://example.com/v2"> <!-- targetNamespace essential for JAXB to work-->
<xs:element name="createSession">
<xs:complexType>
<xs:attribute name="foo" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:schema>