2015-10-17 97 views
0

我試圖發送一個REST請求,響應的第一部分可用但我無法訪問第二部分。無法使用RestTemplate解析REST響應

<SearchResults> 
<TotalHotelsFound>7250</TotalHotelsFound> 
<CheckInDate>2016-01-07</CheckInDate> 
<CheckOutDate>2016-01-09</CheckOutDate> 
<Currency>EUR</Currency> 
<SearchId>HB-82365485</SearchId> 
<Hotels> 
    <Hotel> 
    <HotelCode>FRYX72</HotelCode> 
    <ProcessId>O3-69817815</ProcessId> 
    <BoardType>Room Only</BoardType> 
    <BookingURL>http://www.otel.com/hotels/nomad_paris_roissy_cdg_hotel.htm?processid=HB-82326485FRYX734</BookingURL> 
    <TotalPrice>87</TotalPrice> 
    <FreeCancel>unknown</FreeCancel> 
    <PaymentType>prepaid</PaymentType> 
    <Tax>14</Tax> 
    <AverageNightRate>43</AverageNightRate> 
    <RoomTypes>Double Or Twin/Double Standard</RoomTypes> 
    <AverageRatePerNightPerRoom>43.36</AverageRatePerNightPerRoom> 
    <Rooms> 
    <Room> 
     <Type>double or twin standard</Type> 
     <RoomDesc>Double Or Twin Standard</RoomDesc> 
     <Adults>2</Adults> 
     <Children/> 
     <TotalRate>87</TotalRate> 
     <Tax>12</Tax> 
     <Rates/> 
     <AverageNightRoomRate>43</AverageNightRoomRate> 
    </Room> 
    </Rooms> 
    </Hotel> 
    <Hotel> 
    <HotelCode>FRYX72</HotelCode> 
    <ProcessId>O0-63816095</ProcessId> 
    <BoardType>Room Only</BoardType> 
    <BookingURL>http://www.otel.com/hotels/nomad_paris_roissy_cdg_hotel.htm?processid=HB-82356285FRYX789</BookingURL> 
    <TotalPrice>87</TotalPrice> 
    <FreeCancel>unknown</FreeCancel> 
    <PaymentType>prepaid</PaymentType> 
    <Tax>14</Tax> 
    <AverageNightRate>43</AverageNightRate> 
    <RoomTypes>Double Or Twin/Double Standard</RoomTypes> 
    <AverageRatePerNightPerRoom>43.36</AverageRatePerNightPerRoom> 
    <Rooms> 
     <Room> 
     <Type>double or twin standard</Type> 
     <RoomDesc>Double Or Twin Standard</RoomDesc> 
     <Adults>2</Adults> 
     <Children/> 
     <TotalRate>87</TotalRate> 
     <Tax>12</Tax> 
     <Rates/> 
     <AverageNightRoomRate>43</AverageNightRoomRate> 
     </Room> 
    </Rooms> 
</Hotel> 

代碼

try { 
      System.err.println(">>> Otel"); 
      final String AFFILIATE = "Username"; 
      final String URL = "http://ws.hotelspro.com/xml/test-search-otel.php?affiliate=" 
        + AFFILIATE; 
      String readyUrl = URL + "&country=FR&city=Paris&checkin=2016-1-7&checkout=2016-1-9&currency=EUR&rooms=1&adults1=2"; 
      System.err.println(">>>" + readyUrl); 
      RestTemplate restTemplate = new RestTemplate(); 
      SearchResults searchResults = restTemplate.getForObject(readyUrl, 
        SearchResults.class); 
      if (searchResults == null) { 
       System.err.println("it is null"); 
      } else { 
       System.err.println("message:>>" 
         + searchResults.getTotalHotelsFound()); 
      } 
      System.err.println(">>>" + searchResults.getHotels().size()); 
      System.err.println(">>>" + searchResults.getHotels().get(0).getHotelCode()); 
      System.err.println(">>>" + searchResults.getHotels().get(0).getHotelCode()); 
      System.err 
        .println("Otel>>>" + searchResults.getHotels().get(0).getPaymentType()); 
      System.err.println("event>>" + searchResults.getHotels().get(0).getBookingUrl()); 
     } catch (NullPointerException e) { 
      e.printStackTrace(); 
     } 

JAXB

@XmlRootElement(name = "SearchResults") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class SearchResults { 
    @XmlElement(name = "TotalHotelsFound") 
    private int totalHotelsFound; 
    @XmlElement(name = "CheckInDate") 
    private Date checkInDate; 
    @XmlElement(name = "CheckOutDate") 
    private Date checkOutDate; 
    @XmlElement(name = "Currency") 
    private String currency; 
    @XmlElement(name = "SearchId") 
    private String searchId; 
    @XmlElement(name = "Hotels") 
    private List<Hotel> hotels; 
    getters and setters 


@XmlRootElement(name = "Hotel") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Hotel { 
    @XmlElement(name = "HotelCode") 
    private String hotelCode; 
    @XmlElement(name = "ProcessId") 
    private String processId; 
    @XmlElement(name = "BoardType") 
    private String boardType; 
    @XmlElement(name = "BookingURL") 
    private String bookingUrl; 
    @XmlElement(name = "TotalPrice") 
    private double totalPrice; 
    @XmlElement(name = "FreeCancel") 
    private String freeCancel; 
    @XmlElement(name = "PaymentType") 
    private String paymentType; 
    @XmlElement(name = "Tax") 
    private int tax; 
    @XmlElement(name = "AverageNightRate") 
    private double averageNightRate; 
    @XmlElement(name = "RoomTypes") 
    private String roomType; 
    @XmlElement(name = "AverageRatePerNightPerRoom") 
    private double averageRatePerNightPerRoom; 
    @XmlElement(name = "Rooms") 
    private List<Room> rooms; 
    getters and setters 


@XmlRootElement(name = "Room") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Room { 
    @XmlElement(name = "Type") 
    private String type; 
    @XmlElement(name = "RoomDesc") 
    private String roomDesc; 
    @XmlElement(name = "Adults") 
    private int adults; 
    @XmlElement(name = "Children") 
    private int children; 
    @XmlElement(name = "TotalRate") 
    private double totalRate; 
    @XmlElement(name = "Tax") 
    private double tax; 
    @XmlElement(name = "Rates") 
    private String rates; 
    @XmlElement(name = "AverageNightRoomRate") 
    private int averageNightRoomRate; 
    getters and setters 

輸出

我收到以下ö utput,如下面的第一部分所示,但酒店列表不會被填充。

message:>>7258 
>>>1 
>>>null 
>>>null 
Otel>>>null 
event>>null 
+0

您已正確設置Content-Type以獲取其餘數據。看看http://stackoverflow.com/questions/13038529/force-spring-resttemplate-to-use-xmlconverter如果它對你有幫助 –

+0

你可以嘗試添加@XmlAttribute(name =「hotel」)over酒店的getter方法,如@XmlAttribute(name =「hotel」) –

+0

@BurakKeceli它返回消息:>> 7066 java.lang.NullPointerException \t at com.otel.App.main(App.java:32) – Jack

回答

1

你需要使用@XmlElementWrapper對象列出

@XmlRootElement(name = "SearchResults") 
@XmlAccessorType(XmlAccessType.FIELD) 
public static class SearchResults { 
    @XmlElement(name = "TotalHotelsFound") 
    private int totalHotelsFound; 
    @XmlElement(name = "CheckInDate") 
    private Date checkInDate; 
    @XmlElement(name = "CheckOutDate") 
    private Date checkOutDate; 
    @XmlElement(name = "Currency") 
    private String currency; 
    @XmlElement(name = "SearchId") 
    private String searchId; 
    @XmlElementWrapper(name = "Hotels") 
    @XmlElement(name = "Hotel") 
    private List<Hotel> hotels; 

} 

和相同的房間

+0

I覺得指出這個答案可能有點誤導可能很重要。您沒有明確**需要所有列表的** @XmlElementWrapper作爲泛化。然而,在這種情況下確實有意義,因爲hotels元素不包含任何其他元素。 – kirsty

+0

@XmlElementWrapper是使用jaxb中的集合的有效方式。 –

+0

它的工作原理非常感謝,我會仔細檢查並回復您。 – Jack

0

我相信你可以有一對夫婦失蹤的標籤在你的示例XML,specificaaly </Hotels></SearchResults>

上面的代碼表明您試圖指定多個根元素。首先,這是不正確的。 SearchResults將成爲您的根元素,幷包含所有其他元素。這是更準確的JAXB代碼:

SearchResults類裏:

@XmlRootElement(name = "SearchResults") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class SearchResults { 
    @XmlElement(name = "TotalHotelsFound") 
    private int totalHotelsFound; 
    @XmlElement(name = "CheckInDate") 
    private Date checkInDate; 
    @XmlElement(name = "CheckOutDate") 
    private Date checkOutDate; 
    @XmlElement(name = "Currency") 
    private String currency; 
    @XmlElement(name = "SearchId") 
    private String searchId; 
    @XmlElement(name = "Hotels") 
    private Hotels hotels; 

    //getters and setters 
} 

酒店類:

@XmlAccessorType(XmlAccessType.FIELD) 
public class Hotels { 
    @XmlElement(name = "Hotel") 
    private List<Hotel> hotel; 

    //getters and setters 
} 

飯店等級:

@XmlAccessorType(XmlAccessType.FIELD) 
public class Hotel { 
    @XmlElement(name = "HotelCode") 
    private String hotelCode; 
    @XmlElement(name = "ProcessId") 
    private String processId; 
    ...etc 

    //getters and setters 
} 

我希望這有助於。

+0

我刪除了這些XMLRootElement註釋,並在此行返回NullPointerException System.err.println(「>>>」+ searchResults.getHotels()。size()); – Jack

+0

因此,當您將XML解組到SearchResults對象時,是否使用模式驗證它?在您的打印語句中使用Hotels對象的實例也是值得的,以避免懷疑SearchResults對象整體出現任何問題。 – kirsty