2015-10-17 95 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