0

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
3
  • You have set Content-type properly to fetch remaining data. Have a look at stackoverflow.com/questions/13038529/… if it is helpful for you Commented Oct 17, 2015 at 7:24
  • Can you try to add @XmlAttribute(name="hotel") over the getter method of hotels, like @XmlAttribute(name="hotel") Commented Oct 17, 2015 at 7:59
  • @BurakKeceli it returns message:>>7066 java.lang.NullPointerException at com.otel.App.main(App.java:32) Commented Oct 17, 2015 at 8:09

2 Answers 2

1
+50

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

Sign up to request clarification or add additional context in comments.

3 Comments

I feel it may be important to point out that this answer could be a little misleading. You don't explicitly need @XmlElementWrapper for all lists as a generalization. It does make sense in this case however, because the hotels element doesn't contain any other element
@XmlElementWrapper is efficient way of working with collections in jaxb.
It works thanks I will double check it and get back to you.
0

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.

2 Comments

I removed those XMLRootElement annotations and it returns NullPointerException on this line System.err.println(">>>" + searchResults.getHotels().size());
So when you unmarshal your XML to the SearchResults object, are you validating it with a schema? It may also be worth making an instance of the Hotels object to use in your print statement for the avoidance of doubt that anything is wrong with the SearchResults object as a whole.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.