Can not unmarshall the SOAP response

前端 未结 1 728
天命终不由人
天命终不由人 2020-12-18 11:36

I could send a request and receive the response but I can not parse the response. It returns the following error:

Local Name:Body
error is here
java.lang.Nu         


        
相关标签:
1条回答
  • 2020-12-18 12:26

    Ensure You Are Unmarshalling the Correct Thing

    You need to unmarshal the content held onto by SOAP body, not the entire SOAP message. Below is what the code might look like:

    SOAPMessage sm = response;
    SOAPBody sb = response.getSOAPBody();
    Document d = sb.extractContentAsDocument();
    DOMSource source = new DOMSource(d);
    results = (FindEventsResponse) JAXB.unmarshal(source, FindEventsResponse.class);
    

    The result of sb.extractContentAsDocument is going to be a DOM that is equivalent to the following:

    <?xml version="1.0" encoding="UTF-8"?>
    <ns1:findEventsResponse xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
        xmlns:ns1="http://ticketmaster.productserve.com/v2/soap.php"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
        SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
        <return xsi:type="ns1:Response">
            <details xsi:type="ns1:Details">
                <totalResults xsi:type="xsd:int">20662</totalResults>
                <totalPages xsi:type="xsd:int">414</totalPages>
                <currentPage xsi:type="xsd:int">1</currentPage>
                <resultsPerPage xsi:type="xsd:int">50</resultsPerPage>
            </details>
            <results SOAP-ENC:arrayType="ns1:Event[50]" xsi:type="ns1:ArrayOfEvent">
                <item xsi:type="ns1:Event">
                    <eventId xsi:type="xsd:int">1516682</eventId>
                    <ticketmasterEventId xsi:type="xsd:string">18004C6E8D7218A8</ticketmasterEventId>
                    <status xsi:type="xsd:string">onSale</status>
                    <name xsi:type="xsd:string">The Art of the Brick</name>
                    <url xsi:type="xsd:string">http://www.ticketmaster.ie/event/18004C6E8D7218A8?camefrom=CFC_UK_BUYAT&amp;brand=[=BRAND=]</url>
                    <eventDate xsi:type="xsd:string">2014-05-23 10:00:00</eventDate>
                    <onSaleDate xsi:type="xsd:string">0000-00-00 00:00:00</onSaleDate>
                    <preSaleDate xsi:type="xsd:string">0000-00-00 00:00:00</preSaleDate>
                    <category xsi:type="xsd:string">Exhibitions</category>
                    <categoryId xsi:type="xsd:int">754</categoryId>
                    <parentCategory xsi:type="xsd:string">Family &amp;amp; Attractions</parentCategory>
                    <parentCategoryId xsi:type="xsd:int">10003</parentCategoryId>
                    <minPrice xsi:type="xsd:float">17</minPrice>
                    <maxPrice xsi:type="xsd:float">17</maxPrice>
                    <artists SOAP-ENC:arrayType="ns1:Artist[1]" xsi:type="ns1:ArrayOfArtist">
                        <item xsi:type="ns1:Artist">
                            <artistId xsi:type="xsd:int">1806028</artistId>
                            <ticketmasterArtistId xsi:type="xsd:int">1663495</ticketmasterArtistId>
                            <name xsi:type="xsd:string">The Art of the Brick</name>
                            <url xsi:type="xsd:string">http://www.ticketmaster.co.uk/The-Art-of-the-Brick-tickets/artist/1663495?camefrom=CFC_UK_BUYAT&amp;brand=[=BRAND=]</url>
                            <imageUrl xsi:type="xsd:string">http://media.ticketmaster.com/tm/en-us/tmimages/TM_GenCatImgs_Generic_BW.jpg</imageUrl>
                            <category xsi:type="xsd:string">Miscellaneous</category>
                            <categoryId xsi:type="xsd:int">0</categoryId>
                            <parentCategory xsi:type="xsd:string">Miscellaneous</parentCategory>
                            <parentCategoryId xsi:type="xsd:int">10005</parentCategoryId>
                        </item>
                    </artists>
                    <venue xsi:type="ns1:Venue">
                        <venueId xsi:type="xsd:int">3331</venueId>
                        <ticketmasterVenueId xsi:type="xsd:int">198292</ticketmasterVenueId>
                        <name xsi:type="xsd:string">Ambassador Theatre</name>
                        <street xsi:type="xsd:string">Oconnell Street</street>
                        <city xsi:type="xsd:string">Dublin</city>
                        <country xsi:type="xsd:string">United Kingdom</country>
                        <postcode xsi:type="xsd:string">Dublin 1</postcode>
                        <url xsi:type="xsd:string">http://www.ticketmaster.ie/Ambassador-Theatre-tickets-Dublin/venue/198292?camefrom=CFC_UK_BUYAT&amp;brand=</url>
                        <imageUrl xsi:type="xsd:string">http://media.ticketmaster.co.uk/tmimages/TM_GenVenueImg_BW.jpg</imageUrl>
                        <state xsi:type="xsd:string"></state>
                    </venue>
                </item>
                <item xsi:type="ns1:Event"></item>
            </results>
        </return>
    </ns1:findEventsResponse>
    

    UPDATE

    Based on the new exception you are getting:

    java.lang.IllegalArgumentException: prefix xsd is not bound to a namespace
        at com.sun.xml.internal.bind.DatatypeConverterImpl._parseQName(DatatypeConverterImpl.java:346)
        at com.sun.xml.internal.bind.v2.runtime.unmarshaller.LeafPropertyXsiLoader.selectLoader(LeafPropertyXsiLoader.java:75)
        at com.sun.xml.internal.bind.v2.runtime.unmarshaller.LeafPropertyXsiLoader.startElement(LeafPropertyXsiLoader.java:58)
        at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:486)
        at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:465)
    

    It appears as though sb.extractContentAsDocument(); is not bringing along the xmlns:xsd declaration from the SOAP message. Instead you can change the code to do the following:

    SOAPMessage sm = response;
    SOAPBody sb = response.getSOAPBody();
    DOMSource source = new DOMSource(sb.getFirstChild());
    results = (FindEventsResponse) JAXB.unmarshal(source, FindEventsResponse.class);
    

    Ensure the Namespace Qualification is Mapped Correctly

    Having the following tells JAXB that everything mapped to an XML element without an explicitly specified namespace should belong in the http://ticketmaster.productserve.com/v2/soap.php namespace.

    @XmlSchema( 
        namespace = "http://ticketmaster.productserve.com/v2/soap.php",
        elementFormDefault = XmlNsForm.QUALIFIED) 
    package com.ticketmaster.ticketmaster;
    import javax.xml.bind.annotation.XmlNsForm;
    import javax.xml.bind.annotation.XmlSchema;
    

    In your XML only the findEventsResponse element is namespace qualified. This means your annotation should be the following instead (note change from QUALIFIED to UNQUALIFIED):

    @XmlSchema( 
        namespace = "http://ticketmaster.productserve.com/v2/soap.php",
        elementFormDefault = XmlNsForm.UNQUALIFIED) 
    package com.ticketmaster.ticketmaster;
    import javax.xml.bind.annotation.XmlNsForm;
    import javax.xml.bind.annotation.XmlSchema;
    

    Demo Code

    Using the above XML as input.xml I was able to unmarshal and marshal the model as you have defined it in your question with the @XmlSchema fix mentioned above.

    import javax.xml.bind.*;
    import javax.xml.transform.stream.StreamSource;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            JAXBContext jc = JAXBContext.newInstance(FindEventsResponse.class);
    
            Unmarshaller unmarshaller = jc.createUnmarshaller();
            StreamSource xml = new StreamSource("src/forum23806625/input.xml");
            JAXBElement<FindEventsResponse> response = unmarshaller.unmarshal(xml, FindEventsResponse.class);
    
            Marshaller marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(response, System.out);
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题