无法解组SOAP响应

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

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

响应:

      
20662 414 1 50
1516682 18004C6E8D7218A8 onSale The Art of the Brick http://www.ticketmaster.ie/event/18004C6E8D7218A8?camefrom=CFC_UK_BUYAT&brand=[=BRAND=] 2014-05-23 10:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 Exhibitions 754 Family & Attractions 10003 17 17 1806028 1663495 The Art of the Brick http://www.ticketmaster.co.uk/The-Art-of-the-Brick-tickets/artist/1663495?camefrom=CFC_UK_BUYAT&brand=[=BRAND=] http://sofzh.miximages.com/java/TM_GenCatImgs_Generic_BW.jpg Miscellaneous 0 Miscellaneous 10005 3331 198292 Ambassador Theatre Oconnell Street Dublin United Kingdom Dublin 1 http://www.ticketmaster.ie/Ambassador-Theatre-tickets-Dublin/venue/198292?camefrom=CFC_UK_BUYAT&brand= http://sofzh.miximages.com/java/TM_GenVenueImg_BW.jpg ....

模型类

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

错误是

 ..... >LondonUnited KingdomSE1 8XXhttp://www.ticketmaster.co.uk/The-London-Wonderground-tickets-London/venue/253993?camefrom=CFC_UK_BUYAT&brand=http://sofzh.miximages.com/java/TM_GenVenueImg_BW.jpg >>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:

    
20662 414 1 50
1516682 18004C6E8D7218A8 onSale The Art of the Brick http://www.ticketmaster.ie/event/18004C6E8D7218A8?camefrom=CFC_UK_BUYAT&brand=[=BRAND=] 2014-05-23 10:00:00 0000-00-00 00:00:00 0000-00-00 00:00:00 Exhibitions 754 Family & Attractions 10003 17 17 1806028 1663495 The Art of the Brick http://www.ticketmaster.co.uk/The-Art-of-the-Brick-tickets/artist/1663495?camefrom=CFC_UK_BUYAT&brand=[=BRAND=] http://sofzh.miximages.com/java/TM_GenCatImgs_Generic_BW.jpg Miscellaneous 0 Miscellaneous 10005 3331 198292 Ambassador Theatre Oconnell Street Dublin United Kingdom Dublin 1 http://www.ticketmaster.ie/Ambassador-Theatre-tickets-Dublin/venue/198292?camefrom=CFC_UK_BUYAT&brand= http://sofzh.miximages.com/java/TM_GenVenueImg_BW.jpg

UPDATE

基于您获得的新例外:

 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元素是名称空间限定的。 这意味着您的注释应该是以下内容(注意从UNQUALIFIED更改为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 response = unmarshaller.unmarshal(xml, FindEventsResponse.class); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(response, System.out); } }