Jack
Jack

Reputation: 6620

Cannot parse a REST response with RestTemplate

I am trying to send a REST request, the first part of response is available but I cannot access the second part.

<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>

Code

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

Output

I am receiving following output, as shown below first section is read but Hotels list wont get populated.

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

Upvotes: 0

Views: 1102

Answers (2)

kirsty
kirsty

Reputation: 267

I believe you may have a couple of missing tags in your example XML, specificaaly </Hotels> and </SearchResults>

Your code above suggests that you have tried to specify multiple root elements. First of all, this is incorrect. SearchResults will be your root element, and all other elements are contained. This is more accurate JAXB code:

SearchResults class:

@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
}

Hotels class:

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

    //getters and setters
}

Hotel class:

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

    //getters and setters
}

I hope this helps.

Upvotes: 0

Anatoly Deyneka
Anatoly Deyneka

Reputation: 1258

Your need to use @XmlElementWrapper for Lists

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

}

and the same for the room

Upvotes: 1

Related Questions