我可以发送请求并接收响应,但我无法解析响应。它返回以下错误:
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&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; 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&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&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
}
根据下列答案之一,我编组了结果,结果显示了错误的响应。
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());
<<p> 错误/strong> .....
><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&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主体所保留的内容,而不是整个SOAP消息。下面是代码可能的样子:
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:
<?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&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; 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&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&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>
更新基于你得到的新异常:
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();
没有从SOAP消息中带来xmlns:xsd
声明。相反,您可以将代码更改为以下操作:
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
):
@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作为input.xml
,我能够解组和编组模型,就像你在上面提到的@XmlSchema
修复问题中定义的那样。
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);
}
}
标题>