Как unmarshall SOAP XML для объекта Java [дубликат]

этот вопрос уже есть ответ здесь:

при попытке unmarshall my soap XML to JAXB object я получаю следующую ошибку.

мы получаем ошибку, что ожидаемый элемент является none. Если что-то конкретно сделать, неупорядочивая 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 ответов


Я не думаю, что вы принимаете во внимание конверт с мылом... Сгенерированный JAXB Unmarshaller ничего не будет знать о тегах Body или Envelope, он будет ожидать, что ваш createSession будет корневым элементом, следовательно, ошибка "непредвиденный элемент".

нужно извлечь содержимое из конверта, вы можете сделать это с помощью сообщения.getSOAPBody ().extractContentAsDocument () если сначала создать объект SOAPMessage из содержимого.

это довольно fiddly делать, вот рабочий пример из моего блог

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>