无法解组SOAP响应 [英] Can not unmarshall the SOAP response

查看:134
本文介绍了无法解组SOAP响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以发送请求并收到回复,但我无法解析回复。它返回以下错误:

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.NullPointerException
    at com.ticketmaster.ticketmaster.TicketMaster.Search(TicketMaster.java:119)
    at com.ticketmaster.ticketmaster.App.main(App.java:12)

代码

    SOAPMessage response
            = connection.call(message, endpoint);

    connection.close();
        SOAPMessage sm = response;
        SOAPBody sb = response.getSOAPBody();
        System.err.println("Node Name:" + sb.getNodeName());  //return nothing
        System.err.println("Local Name:" + sb.getLocalName());  //return Local Name:Body

        DOMSource source = new DOMSource(sb);
        results = (FindEventsResponse) JAXB.unmarshal(source, FindEventsResponse.class);
        System.err.println("Results size: " + this.results.returnTag.results.item.get(0).getName());

} catch (Exception ex) {
    System.err.println("error is here");
    ex.printStackTrace();
}

回复:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope 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/">
    <SOAP-ENV:Body>
        <ns1:findEventsResponse>
            <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">
                     ....

模型类

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class FindEventsResponse {
    @XmlElement(name = "return")
    Return returnTag;

    public FindEventsResponse() {
       this.returnTag = new Return();
    }
    getter and setter

}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Return {
    @XmlElement(name = "details")
    Details details;
    @XmlElement(name = "results")
    Results results;

    public Return(Details details, Results results) {
       this.details = new Details();
       this.results = new Results();
    }
    getters and setters


}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Details {

    @XmlElement(name = "totalResults")
    int totalResults;
    @XmlElement(name = "totalPages")
    int totalPages;
    @XmlElement(name = "currentPage")
    int currentPage;
    @XmlElement(name = "resultPerPage")
    int resultsPerPage;

     getters and setters

}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Results {
    @XmlElement(name = "item")
    List<Item> item;

    public Results() {
       this.item = new ArrayList();
    }
    getter and setter



}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Item {

    @XmlElement(name = "eventId")
    int eventId;
    @XmlElement(name = "ticketmasterEventId")
    String ticketmasterEventId;
    @XmlElement(name = "status")
    String status;
    @XmlElement(name = "name")
    String name;
    @XmlElement(name = "url")
    String url;
    @XmlElement(name = "eventDate")
    String eventDate;
    @XmlElement(name = "onSaleDate")
    String onSaleDate;
    @XmlElement(name = "preSaleDate")
    String preSaleDate;
    @XmlElement(name = "category")
    String category;
    @XmlElement(name = "categoryId")
    int categoryId;
    @XmlElement(name = "parentCategory")
    String parentCategory;
    @XmlElement(name = "parentCategoryId")
    int parentCategoryId;
    @XmlElement(name = "minPrice")
    int minPrice;
    @XmlElement(name = "maxPrice")
    int maxPrice;
    @XmlElement(name = "artists")
    private Artists artist;
    @XmlElement(name = "venue")
    private Venue venue;

    public Item() {
       this.artist = new Artists();
       this.venue = new Venue();
    }

    getters and setters

}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Artists {
    @XmlElement(name = "artists")
    private ArtistItem item;

    public Artists() {
        this.item = new ArtistItem();
    }
    getter and setter
}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class ArtistItem {

    @XmlElement(name = "artistId")
    int artistId;
    @XmlElement(name = "ticketmasterArtistsId")
    int ticketmasterArtistId;
    @XmlElement(name = "name")
    String name;
    @XmlElement(name = "url")
    String url;
    @XmlElement(name = "imageUrl")
    String imageUrl;
    @XmlElement(name = "category")
    String category;
    @XmlElement(name = "categoryId")
    int categoryId;
    @XmlElement(name = "parentCategory")
    String parentCategory;
    @XmlElement(name = "parentCategoryId")
    int parentCategoryId;

    getters and setters
}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Venue {

    @XmlElement(name = "venueId")
    int venueId;
    @XmlElement(name = "ticketmasterVenueId")
    int ticketmasterVenueId;
    @XmlElement(name = "name")
    String name;
    @XmlElement(name = "street")
    String street;
    @XmlElement(name = "city")
    String city;
    @XmlElement(name = "country")
    String country;
    @XmlElement(name = "postcode")
    String postcode;
    @XmlElement(name = "url")
    String url;
    @XmlElement(name = "imageUrl")
    String imageUrl;
    @XmlElement(name = "state")
    String state;

    getters and setters
}

基于其中一个以下答案,我整理了结果并显示错误的回复。

Based on one of the following answers, I marshalled the result and it shows a wrong response.

package-info.java

@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;

代码

    SOAPBody sb = response.getSOAPBody();
System.err.println(">>"+ sb.getFirstChild().getNodeName());
Iterator itr = sb.getChildElements();
while(itr.hasNext()){
    Object element = itr.next();
    System.err.println(element + " ");
}
Document d = sb.extractContentAsDocument();
System.err.println("result of d:"+d.getTextContent());
DOMSource source = new DOMSource(d);
results = (FindEventsResponse) JAXB.unmarshal(source, FindEventsResponse.class);
System.err.println("results>"+results.getReturnTag().getResults().getItem().get(0).getName());

错误

.....
><city xsi:type="xsd:string">London</city><country xsi:type="xsd:string">United Kingdom</country><postcode xsi:type="xsd:string">SE1 8XX</postcode><url xsi:type="xsd:string">http://www.ticketmaster.co.uk/The-London-Wonderground-tickets-London/venue/253993?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></results></return></ns1:findEventsResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>

>>ns1:findEventsResponse
[ns1:findEventsResponse: null] 
result of d:null
error is here

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)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.InterningXmlVisitor.startElement(InterningXmlVisitor.java:60)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:135)
    at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:229)
    at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:266)
    at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:235)
    at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:266)
    at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:235)
    at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:266)
    at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:235)
    at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:266)
    at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:235)
    at com.sun.xml.internal.bind.unmarshaller.DOMScanner.scan(DOMScanner.java:112)
    at com.sun.xml.internal.bind.unmarshaller.DOMScanner.scan(DOMScanner.java:95)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:312)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:288)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:238)
    at javax.xml.bind.JAXB.unmarshal(JAXB.java:259)
    at com.ticketmaster.ticketmaster.TicketMaster.Search(TicketMaster.java:132)
    at com.ticketmaster.ticketmaster.App.main(App.java:12)   


推荐答案

确保你正在解组正确的东西



你需要解组由 SOAP body 保留的内容,而不是整个 SOAP消息。下面是代码的样子:

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);

sb.extractContentAsDocument 的结果即将发生是一个相当于以下的DOM:

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



基于新例外你得到:

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)

好像 sb.extractContentAsDocument(); 没有携带 xmlns:xsd 来自SOAP混乱的声明年龄。相反,您可以更改代码以执行以下操作:

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);



确保命名空间限定正确映射



具有以下内容告诉JAXB,映射到没有明确指定的命名空间的XML元素的所有内容都应属于 http://ticketmaster.productserve.com/v2/soap.php 命名空间。

@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;

在XML中只有 findEventsResponse 元素是命名空间合格这意味着您的注释应该是以下内容(注意从 QUALIFIED 更改为 UNQUALIFIED ):

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;



演示代码



使用上述XML as input.xml 我能够解组和编组模型,因为你已经在 @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);
    }

}

这篇关于无法解组SOAP响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆