解析的SOAP响应与接收的响应不同

我试图解析SOAP响应。 我可以使用以下行显示完整的响应。

System.out.println("Response: " + out.toString()); 

但是,当我解析响应并对解析后的响应进行编组时,它会显示错误的响应。

package-info.java

 @XmlSchema( namespace = "http://v3.hotel.wsapi.ean.com/", elementFormDefault = XmlNsForm.QUALIFIED) package com.ean; import javax.xml.bind.annotation.XmlNsForm; import javax.xml.bind.annotation.XmlSchema; 

我的代码

 @XmlRootElement(name="getListResponse") @XmlAccessorType(XmlAccessType.FIELD) public class GetListResponse { @XmlElement(name="HotelListResponse") private HotelListResponse hotelListResponse; public GetListResponse() { this.hotelListResponse = new HotelListResponse(); } …getter and setter } @XmlRootElement(name ="HotelListResponse") @XmlAccessorType(XmlAccessType.FIELD) public class HotelListResponse { @XmlElement(name = "customerSessionId") String customerSessionId; @XmlElement(name = "numberOfRoomsRequested") int numberOfRoomsRequested; @XmlElement(name = "moreResultsAvailable") boolean moreResultsAvailable; @XmlElement(name = "cacheKey") String cacheKey; @XmlElement(name="cacheLocation") String cachLocation; @XmlElement(name = "HotelList") HotelList hotelList; public HotelListResponse() { this.hotelList = new HotelList(); } … getters and setters… } @XmlRootElement(name ="HotelList") @XmlAccessorType(XmlAccessType.FIELD) public class HotelList { @XmlAttribute(name = "size") int size; @XmlAttribute(name = "activePropertyCount") int activePropertyCount; @XmlElement(name = "HotelSummary") List  hotelSummaries; public HotelList() { this.hotelSummaries = new ArrayList(); } … getters and setters… } @XmlRootElement(name = "HotelSummary") @XmlAccessorType(XmlAccessType.FIELD) public class HotelSummary { @XmlAttribute(name = "order") int order; @XmlElement(name = "hotelId") int hotelId; @XmlElement(name = "name") String name; @XmlElement(name = "address1") String address1; @XmlElement(name = "city") String city; @XmlElement(name = "stateProvinceCode") String stateProvinceCode; @XmlElement(name = "postalCode") int postalCode; @XmlElement(name = "countryCode") String countryCode; @XmlElement(name = "airportCode") String airportCode; @XmlElement(name = "supplierType") String supplierType; @XmlElement(name = "propertyCategory") int propertyCategory; @XmlElement(name = "hotelRating") float hotelRating; @XmlElement(name = "confidenceRating") int confidenceRating; @XmlElement(name = "amenityMask") int amenityMask; @XmlElement(name = "tripAdvisorRating") float tripAdvisorRating; @XmlElement(name = "locationDescription") String locationDescription; @XmlElement(name = "shortDescription") String shortDescriptionl; //change amp to & @XmlElement(name = "highRate") String highRate; @XmlElement(name = "lowRate") float lowRate; @XmlElement(name = "rateCurrencyCode") String rateCurrencyCode; @XmlElement(name = "latitude") float latitude; @XmlElement(name = "longitude") float longitude; @XmlElement(name = "proximityDistance") float proximityDistance; @XmlElement(name = "proximityUnit") String proximityUnit; @XmlElement(name = "hotelInDestination") boolean hotelInDestination; @XmlElement(name = "thumbNailUrl") String thumbNailUrl; @XmlElement(name = "deepLink") String deepLink; @XmlElement(name = "RoomRateDetailsList") RoomRateDetailsList roomRateDetailsList; public HotelSummary() { this.roomRateDetailsList = new RoomRateDetailsList(); } … getters and setters… } @XmlRootElement(name = "RoomRateDetailsList") @XmlAccessorType(XmlAccessType.FIELD) public class RoomRateDetailsList { @XmlElement(name="RoomRateDetails") List roomRateDetails; public RoomRateDetailsList() { this.roomRateDetails = new ArrayList(); } .. getter and setter.. } @XmlRootElement(name = "RoomRateDetails") @XmlAccessorType(XmlAccessType.FIELD) public class RoomRateDetails { @XmlElement(name="roomTypeCode") int roomTypeCode; @XmlElement(name="rateCode") int rateCode; @XmlElement(name="maxRoomOccupancy") int maxRoomOccupancy; @XmlElement(name="quotedRoomOccupancy") int quotedRoomOccupancy; @XmlElement(name="minGuestAge") int minGuestAge; @XmlElement(name="roomDescription") String roomDescription; @XmlElement(name="promoId") int promoId; @XmlElement(name="promoDescription") String promoDescription; @XmlElement(name="currentAllotment") int currentAllotment; @XmlElement(name="propertyAvailable") boolean propertyAvailable; @XmlElement(name="propertyRestricted") boolean propertyRestricted; @XmlElement(name="expediaPropertyId") int expediaPropertyId; @XmlElement(name="rateKey") String rateKey; @XmlElement(name="RateInfo") RateInfo rateInfo; @XmlElement(name="ValueAdds") ValueAdds valueAdds; public RoomRateDetails() { this.rateInfo = new RateInfo(); this.valueAdds = new ValueAdds(); } … getters and setters… } @XmlRootElement(name = "RoomInfo") @XmlAccessorType(XmlAccessType.FIELD) public class RateInfo { @XmlAttribute(name="priceBreakdown") boolean priceBreakdown; @XmlAttribute(name="promo") boolean promo; @XmlAttribute(name="rateChange") boolean rateChange; @XmlElement(name="ChargeableRateInfo") ChargeableRateInfo chargeableRateInfo; public RateInfo() { this.chargeableRateInfo = new ChargeableRateInfo(); } .. getters and setters… } @XmlRootElement(name = "ChargeableRateInfo") @XmlAccessorType(XmlAccessType.FIELD) public class ChargeableRateInfo { @XmlAttribute(name="averageBaseRate") float averageBaseRate; @XmlAttribute(name="averageRate") float averageRate; @XmlAttribute(name="commissionableUsdTotal") float commissionableUsdTotal; @XmlAttribute(name="currencyCode") String currencyCode; @XmlAttribute(name="maxNightlyRate") float maxNightlyRate; @XmlAttribute(name="nightlyRateTotal") float nightlyRateTotal; @XmlAttribute(name="total") float total; @XmlElement(name="NightlyRatesPerRoom") NightlyRatesPerRoom nightlyRatesPerRoom; public ChargeableRateInfo() { this.nightlyRatesPerRoom = new NightlyRatesPerRoom(); } … getters and setters… } @XmlRootElement(name = "NightlyRatesPerRoom") @XmlAccessorType(XmlAccessType.FIELD) public class NightlyRatesPerRoom { @XmlAttribute(name="size") int size; @XmlElement(name="NightlyRate") NightlyRate nightlyRate; public NightlyRatesPerRoom() { this.nightlyRate = new NightlyRate(); } … getters and setters… } @XmlRootElement(name = "NightlyRate") @XmlAccessorType(XmlAccessType.FIELD) public class NightlyRate { @XmlAttribute(name="baseRate") float baseRate; @XmlAttribute(name="rate") float rate; @XmlAttribute(name="promo") float promo; public NightlyRate() { } … getters and setters… } @XmlRootElement(name = "ValueAdds") @XmlAccessorType(XmlAccessType.FIELD) public class ValueAdds { @XmlAttribute(name="size") private int size; @XmlElement(name="ValueAdd") private List valueAdd; public ValueAdds() { this.valueAdd = new ArrayList(); } … getters and setters… } @XmlRootElement(name = "ValueAdd") @XmlAccessorType(XmlAccessType.FIELD) public class ValueAdd { @XmlAttribute(name="id") private int id; @XmlElement(name="description") private String description; public ValueAdd() { } … getters and setters… } 

 try { SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance(); SOAPConnection connection = soapConnectionFactory.createConnection(); SOAPFactory soapFactory = SOAPFactory.newInstance(); MessageFactory factory = MessageFactory.newInstance(); SOAPMessage message = factory.createMessage(); SOAPHeader header = message.getSOAPHeader(); header.detachNode(); SOAPBody body = message.getSOAPBody(); Name bodyName; bodyName = soapFactory.createName("getList", "v3", "http://v3.hotel.wsapi.ean.com/"); SOAPBodyElement getList = body.addBodyElement(bodyName); Name childName = soapFactory.createName("HotelListRequest"); SOAPElement HotelListRequest = getList.addChildElement(childName); ……Here, I add child nodes of the request…... message.writeTo(System.out); //show message details URL endpoint = new URL("http://dev.api.ean.com/ean-services/ws/hotel/v3"); SOAPMessage response = connection.call(message, endpoint); connection.close(); SOAPMessage sm = response; System.err.println("Response:"); ByteArrayOutputStream out = new ByteArrayOutputStream(); sm.writeTo(out); System.err.println(">>>" + out.toString()); System.err.println(">>>>>>>>>>>parse:"); SOAPBody sb = response.getSOAPBody(); DOMSource source = new DOMSource(sb); HotelListResponse results = new HotelListResponse(); results = (HotelListResponse) JAXB.unmarshal(source, HotelListResponse.class); JAXBContext context = JAXBContext.newInstance(HotelListResponse.class); Marshaller m = context.createMarshaller(); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); System.err.println("Response *******"); m.marshal(results, System.out); System.err.println("116872:" + results.getHotelList().getHotelSummaries().get(0).getHotelId()); } catch (Exception ex) { ex.printStackTrace(); } 

实际rest

  Response: Response:>>>    0ABAAA95-28B2-5914-7952-0331AC9069EA 1 true -41118b29:146950321ac:-69e1 10.176.160.143:7300   150241 Rydges World Square 389 Pitt Street Sydney NW 2000 AU SYD E 1 4.5 52 1343491 3.5 Near Darling Harbour <p><b>Property Location</b> <br />With a stay at Rydges World Square, you'll be centrally located in Sydney, steps from World Square Shopping Centre and minutes from Capitol Theatre. This 4.5-star 218.64 218.64 USD -33.8766 151.20752 0.5492472 MI true /hotels/1000000/570000/565000/564969/564969_91_t.jpg http://travel.ian.com/index.jsp?pageName=hotAvail&cid=55505&hotelID=150241&mode=2&numberOfRooms=1&room-0-adult-total=2&room-0-child-total=0&arrivalMonth=5&arrivalDay=18&departureMonth=5&departureDay=19&showInfo=true&locale=en_US&currencyCode=USD   200156055 202768754 2 2 0 Special: Deluxe King - Check-In from 8:30pm 201528081 Sale! Save 25% on this Stay. 10 true false 564969 0ABAAA85-18B2-9914-6952-0351AC9069DF          Free Wireless Internet     ... >>>>>>>>>>>parse: Response *******   0 false   java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 at java.util.ArrayList.rangeCheck(ArrayList.java:635) at java.util.ArrayList.get(ArrayList.java:411) at com.expedia.Engine.retrieveHotels(Engine.java:135) at com.hotelsdotcom.App.main(App.java:17) 

如何解决问题

在适当的水平解组

目前,您正在解组与soap:Body元素对应的XML节点,而您需要向下导航到HotelListResponse元素并解组它。

您可以尝试以下方法:

 DOMSource source = new DOMSource(sb.getFirstChild().getFirstChild()); 

观看您的命名空间资格

在您编组的XML中,所有元素都显示为使用http://v3.hotel.wsapi.ean.com/限定,您尝试解组的文档没有此命名空间限定条件,因此您应该删除@XmlSchema package-info类中的@XmlSchema注释。

使用Unmarshaller而不是JAXB.unmarshal

而不是做以下事情:

 results = (HotelListResponse) JAXB.unmarshal(source, HotelListResponse.class); 

我建议做:

 JAXBContext jc = JAXBContext.newInstance(HotelListResponse.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); results = unmarshaller.unmarshal(source, HotelListResponse.class).getValue(); 

什么现在发生

当您使用带有类参数的unmarshal方法时,您告诉JAXB XML对应的是哪个类,而不是由根元素自动确定。

 results = (HotelListResponse) JAXB.unmarshal(source, HotelListResponse.class) 

由于XML文档的级别错误,因此JAXB无法将其中任何一个与您的域模型匹配。 因此,仅填充默认值。 这就是为什么结果充满了0false的值。

   0 false