6

I have following code to send request and receive a response, it seems like everything is configured but the code is returning NullPointerException.

I am not sure whats missing. I printed out readyURL variable which has the correct URL address. The stackTrace does not offer much.

Code

try {
    final String APIKEY = "MYAPI";
    final String URL = "http://api-sandbox.seatwave.com/v2/discovery/events?apikey="
            + APIKEY;
    String readyUrl = URL + "&what=" + name;
    RestTemplate restTemplate = new RestTemplate();
    EventsResponse eventResponse = restTemplate.getForObject(readyUrl,
            EventsResponse.class);

    System.err.println("seatwave>>>"
            + eventResponse.getEvents().getEvent().size()); //line 245
} catch (NullPointerException e) {
    e.printStackTrace();
}


@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class EventsResponse {
    @XmlElement
    private Status status;
    @XmlElement(name = "Paging")
    private Page page;
    @XmlElement
    private Events events;

    public Status getStatus() {
      return status;
    }

    public void setStatus(Status status) {
      this.status = status;
    }

    public Page getPage() {
      return page;
    }

    public void setPage(Page page) {
      this.page = page;
    }

    public Events getEvents() {
      return events;
    }

    public void setEvents(Events events) {
      this.events = events;
    }
}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Status {
    @XmlElement(name = "Version")
    private double version;
    @XmlElement(name = "TimeStampUtc")
    private Date timeStampUtc;
    @XmlElement(name = "Code")
    private int code;
    @XmlElement(name = "Message")
    private String message;
    @XmlElement(name = "Details")
    private String details;

   public double getVersion() {
      return version;
   }

    public void setVersion(double version) {
      this.version = version;
    }

    public Date getTimeStampUtc() {
      return timeStampUtc;
    }

    public void setTimeStampUtc(Date timeStampUtc) {
      this.timeStampUtc = timeStampUtc;
    }

    public int getCode() {
     return code;
    }

  public void setCode(int code) {
     this.code = code;
  }

  public String getMessage() {
     return message;
  }

  public void setMessage(String message) {
     this.message = message;
  }

  public String getDetails() {
     return details;
  }

  public void setDetails(String details) {
     this.details = details;
  }
}

@XmlRootElement(name="Page")
@XmlAccessorType(XmlAccessType.FIELD)
public class Page {
    @XmlElement(name="PageNumber")
    private int pageNumber;
    @XmlElement(name="PageSize")
    private int pageSize;
    @XmlElement(name="PageResultCount")
    private int pageResultCount;
    @XmlElement(name="TotalResultCount")
    private int totalResultCount;
    @XmlElement(name="TotalPageCount")
    private int totalPageCount;

    public int getPageNumber() {
      return pageNumber;
    }

    public void setPageNumber(int pageNumber) {
       this.pageNumber = pageNumber;
    }

    public int getPageSize() {
      return pageSize;
   }

   public void setPageSize(int pageSize) {
      this.pageSize = pageSize;
   }

   public int getPageResultCount() {
      return pageResultCount;
   }

   public void setPageResultCount(int pageResultCount) {
      this.pageResultCount = pageResultCount;
   }

   public int getTotalResultCount() {
      return totalResultCount;
   }

   public void setTotalResultCount(int totalResultCount) {
      this.totalResultCount = totalResultCount;
   }

   public int getTotalPageCount() {
      return totalPageCount;
   }

   public void setTotalPageCount(int totalPageCount) {
     this.totalPageCount = totalPageCount;
   }

}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Events {
    @XmlElement
    private List<Event> event;

    public List<Event> getEvent() {
      return event;
    }  

    public void setEvent(List<Event> event) {
      this.event = event;
    }
 }

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Event {
    @XmlElement(name = "Id")
    private int id;
    @XmlElement(name = "Date")
    private Date date;
    @XmlElement(name = "EventGroupName")
    private String eventGroupName;
    @XmlElement(name = "VenueName")
    private String venueName;
    @XmlElement(name = "Town")
    private String town;
    @XmlElement(name = "Country")
    private String country;
    @XmlElement(name = "TicketCount")
    private int ticketCount;
    @XmlElement(name = "Currency")
    private String currency;
    @XmlElement(name = "MinPrice")
    private double minPrice;
    @XmlElement(name = "SwURL")
    private String swUrl;
    @XmlElement(name = "EventGroupImageURL")
    private String eventGroupImageUrl;
    @XmlElement(name = "LayoutId")
    private int layoutId;
    @XmlElement(name = "EventGroupId")
    private int eventGroupId;
    @XmlElement(name = "VenueId")
    private int venueId;
    @XmlElement(name = "SwSellURL")
    private String swSellUrl;

  public int getId() {
    return id;
  }

  public void setId(int id) {
      this.id = id;
  }

  public Date getDate() {
      return date;
  }

  public void setDate(Date date) {
      this.date = date;
  }

  public String getEventGroupName() {
     return eventGroupName;
  }

  public void setEventGroupName(String eventGroupName) {
        this.eventGroupName = eventGroupName;
  }

  public String getVenueName() {
      return venueName;
  }

  public void setVenueName(String venueName) {
      this.venueName = venueName;
  }

  public String getTown() {
     return town;
  }

  public void setTown(String town) {
     this.town = town;
  }

  public String getCountry() {
     return country;
  }

  public void setCountry(String country) {
        this.country = country;
  }

  public int getTicketCount() {
        return ticketCount;
  }

  public void setTicketCount(int ticketCount) {
        this.ticketCount = ticketCount;
  }

  public String getCurrency() {
        return currency;
  }

  public void setCurrency(String currency) {
        this.currency = currency;
  }

  public double getMinPrice() {
        return minPrice;
  }

  public void setMinPrice(double minPrice) {
        this.minPrice = minPrice;
  }

  public String getSwUrl() {
        return swUrl;
  }

  public void setSwUrl(String swUrl) {
        this.swUrl = swUrl;
  }

  public String getEventGroupImageUrl() {
        return eventGroupImageUrl;
  }

  public void setEventGroupImageUrl(String eventGroupImageUrl) {
        this.eventGroupImageUrl = eventGroupImageUrl;
  }

  public int getLayoutId() {
        return layoutId;
  }

  public void setLayoutId(int layoutId) {
        this.layoutId = layoutId;
  }

  public int getEventGroupId() {
        return eventGroupId;
  }

  public void setEventGroupId(int eventGroupId) {
        this.eventGroupId = eventGroupId;
  }

  public int getVenueId() {
        return venueId;
  }

  public void setVenueId(int venueId) {
        this.venueId = venueId;
  }

  public String getSwSellUrl() {
        return swSellUrl;
  }

  public void setSwSellUrl(String swSellUrl) {
        this.swSellUrl = swSellUrl;
  }
}

Exception

java.lang.NullPointerException
    at com.myproject.tickets.service.TicketSeviceImpl.seatWave(TicketSeviceImpl.java:245)
    at com.myproject.tickets.service.TicketSeviceImpl.findTicket(TicketSeviceImpl.java:45)
    at com.myproject.web.TicketController.findTicket(TicketController.java:29)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:777)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:706)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:369)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
    at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:112)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
    at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:177)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:187)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:168)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)

Sample result

<?xml version="1.0" encoding="UTF-8"?>
<EventsResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
   <Status>
      <Version>2.0</Version>
      <TimeStampUtc>2015-09-27T08:44:24</TimeStampUtc>
      <Code>0</Code>
      <Message>Success</Message>
      <Details />
   </Status>
   <Paging>
      <PageNumber>1</PageNumber>
      <PageSize>50</PageSize>
      <PageResultCount>50</PageResultCount>
      <TotalResultCount>7889</TotalResultCount>
      <TotalPageCount>158</TotalPageCount>
   </Paging>
   <Events>
      <Event>
         <Id>948040</Id>
         <Date>2015-09-27T14:30:00</Date>
         <EventGroupName>The Lion King - London</EventGroupName>
         <VenueName>Lyceum Theatre London</VenueName>
         <Town>London</Town>
         <Country>UK</Country>
         <TicketCount>183</TicketCount>
         <Currency>GBP</Currency>
         <MinPrice>29.75</MinPrice>
         <SwURL>http://www.seatwave.com/the-lion-king-london-tickets/lyceum-theatre--tickets/27-september-2015/perf/948040?affid=&amp;appid=203710</SwURL>
         <EventGroupImageURL>http://z.stwv.im/filestore/season/image/the-lion-king_000277_1_mainpicture.jpg</EventGroupImageURL>
         <LayoutId>232</LayoutId>
         <EventGroupId>277</EventGroupId>
         <VenueId>232</VenueId>
         <SwSellURL>http://www.seatwave.com/sellticketdetails?performanceId=948040&amp;affid=&amp;appid=2037810</SwSellURL>
      </Event>
      <Event>
         <Id>987509</Id>
         <Date>2015-09-27T15:00:00</Date>
         <EventGroupName>American Idiot</EventGroupName>
         <VenueName>Arts Theatre London</VenueName>
         <Town>London</Town>
         <Country>UK</Country>
         <TicketCount>28</TicketCount>
         <Currency>GBP</Currency>
         <MinPrice>35.7</MinPrice>
         <SwURL>http://www.seatwave.com/american-idiot-tickets/arts-theatre-tickets/27-september-2015/perf/987509?affid=&amp;appid=2037810</SwURL>
         <EventGroupImageURL>http://z.stwv.im/filestore/season/image/americanidiot_32152_1_1_20111209091615.jpg</EventGroupImageURL>
         <LayoutId>4576</LayoutId>
         <EventGroupId>32152</EventGroupId>
         <VenueId>4207</VenueId>
         <SwSellURL>http://www.seatwave.com/sellticketdetails?performanceId=987509&amp;affid=&amp;appid=2037810</SwSellURL>
      </Event>
      <Event>
         <Id>948273</Id>
         <Date>2015-09-27T15:00:00</Date>
         <EventGroupName>Matilda The Musical</EventGroupName>
         <VenueName>Cambridge Theatre</VenueName>

Update

I added this code right after restTemplate.getForObject line but nothing will be shown on console.

if(eventResponse == null)
            {
                System.err.println("it is null");
            }else{

            System.err.println("message:>>"+eventResponse.getStatus().getMessage());
            }
Daniel Newtown
  • 2,873
  • 8
  • 30
  • 64

3 Answers3

1

I made your code working by some mapping changes:

@XmlRootElement(name = "EventsResponse") // added (name = "EventsResponse")
@XmlAccessorType(XmlAccessType.FIELD)
public class EventsResponse {
    @XmlElement(name = "Status")
    private Status status;
    @XmlElement(name = "Paging")
    private Page page;
    @XmlElementWrapper(name="Events") // added
    @XmlElement(name = "Event") // added (name = "Event")
    private List<Event> events;

    // getters, setter
}

@XmlRootElement // removed name =
@XmlAccessorType(XmlAccessType.FIELD)
public class Page {
    @XmlElement(name = "PageNumber")
    private int pageNumber;
    @XmlElement(name = "PageSize")
    private int pageSize;
    @XmlElement(name = "PageResultCount")
    private int pageResultCount;
    @XmlElement(name = "TotalResultCount")
    private int totalResultCount;
    @XmlElement(name = "TotalPageCount")
    private int totalPageCount;

    // getters, setter
}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Status {
    @XmlElement(name = "Version")
    private double version;
    @XmlElement(name = "TimeStampUtc")
    private Date timeStampUtc;
    @XmlElement(name = "Code")
    private int code;
    @XmlElement(name = "Message")
    private String message;
    @XmlElement(name = "Details")
    private String details;

    // getters, setter
}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Event {
    @XmlElement(name = "Id")
    private int id;
    @XmlElement(name = "Date")
    private Date date;
    @XmlElement(name = "EventGroupName")
    private String eventGroupName;
    @XmlElement(name = "VenueName")
    private String venueName;
    @XmlElement(name = "Town")
    private String town;
    @XmlElement(name = "Country")
    private String country;
    @XmlElement(name = "TicketCount")
    private int ticketCount;
    @XmlElement(name = "Currency")
    private String currency;
    @XmlElement(name = "MinPrice")
    private double minPrice;
    @XmlElement(name = "SwURL")
    private String swUrl;
    @XmlElement(name = "EventGroupImageURL")
    private String eventGroupImageUrl;
    @XmlElement(name = "LayoutId")
    private int layoutId;
    @XmlElement(name = "EventGroupId")
    private int eventGroupId;
    @XmlElement(name = "VenueId")
    private int venueId;
    @XmlElement(name = "SwSellURL")
    private String swSellUrl;

    // getters, setter
}

then I did test it using Wiremock:

package so32806530;

import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
import org.springframework.web.client.RestTemplate;

import static com.github.tomakehurst.wiremock.client.WireMock.*;

public class App {

    private static final String XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
            "<EventsResponse xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">\n" +
            "   <Status>\n" +
            "      <Version>2.0</Version>\n" +
            "      <TimeStampUtc>2015-09-27T08:44:24</TimeStampUtc>\n" +
            "      <Code>0</Code>\n" +
            "      <Message>Success</Message>\n" +
            "      <Details />\n" +
            "   </Status>\n" +
            "   <Paging>\n" +
            "      <PageNumber>1</PageNumber>\n" +
            "      <PageSize>50</PageSize>\n" +
            "      <PageResultCount>50</PageResultCount>\n" +
            "      <TotalResultCount>7889</TotalResultCount>\n" +
            "      <TotalPageCount>158</TotalPageCount>\n" +
            "   </Paging>\n" +
            "   <Events>\n" +
            "      <Event>\n" +
            "         <Id>948040</Id>\n" +
            "         <Date>2015-09-27T14:30:00</Date>\n" +
            "         <EventGroupName>The Lion King - London</EventGroupName>\n" +
            "         <VenueName>Lyceum Theatre London</VenueName>\n" +
            "         <Town>London</Town>\n" +
            "         <Country>UK</Country>\n" +
            "         <TicketCount>183</TicketCount>\n" +
            "         <Currency>GBP</Currency>\n" +
            "         <MinPrice>29.75</MinPrice>\n" +
            "         <SwURL>http://www.seatwave.com/the-lion-king-london-tickets/lyceum-theatre--tickets/27-september-2015/perf/948040?affid=&amp;appid=203710</SwURL>\n" +
            "         <EventGroupImageURL>http://z.stwv.im/filestore/season/image/the-lion-king_000277_1_mainpicture.jpg</EventGroupImageURL>\n" +
            "         <LayoutId>232</LayoutId>\n" +
            "         <EventGroupId>277</EventGroupId>\n" +
            "         <VenueId>232</VenueId>\n" +
            "         <SwSellURL>http://www.seatwave.com/sellticketdetails?performanceId=948040&amp;affid=&amp;appid=2037810</SwSellURL>\n" +
            "      </Event>\n" +
            "      <Event>\n" +
            "         <Id>987509</Id>\n" +
            "         <Date>2015-09-27T15:00:00</Date>\n" +
            "         <EventGroupName>American Idiot</EventGroupName>\n" +
            "         <VenueName>Arts Theatre London</VenueName>\n" +
            "         <Town>London</Town>\n" +
            "         <Country>UK</Country>\n" +
            "         <TicketCount>28</TicketCount>\n" +
            "         <Currency>GBP</Currency>\n" +
            "         <MinPrice>35.7</MinPrice>\n" +
            "         <SwURL>http://www.seatwave.com/american-idiot-tickets/arts-theatre-tickets/27-september-2015/perf/987509?affid=&amp;appid=2037810</SwURL>\n" +
            "         <EventGroupImageURL>http://z.stwv.im/filestore/season/image/americanidiot_32152_1_1_20111209091615.jpg</EventGroupImageURL>\n" +
            "         <LayoutId>4576</LayoutId>\n" +
            "         <EventGroupId>32152</EventGroupId>\n" +
            "         <VenueId>4207</VenueId>\n" +
            "         <SwSellURL>http://www.seatwave.com/sellticketdetails?performanceId=987509&amp;affid=&amp;appid=2037810</SwSellURL>\n" +
            "      </Event>\n" +
            "   </Events>\n" +
            "</EventsResponse>";

    public static void main(final String[] args) {
        // ---------- starts fake API server -----
        final WireMockServer wireMockServer = new WireMockServer(WireMockConfiguration.wireMockConfig().port(8089));
        wireMockServer.stubFor(get(urlMatching("/v2/discovery/events.*")).willReturn(aResponse().withHeader("Content-type", "application/xml").withStatus(200).withBody(XML)));
        wireMockServer.start();
        // ---------------------------------------

        try {
            final String name = "foo";
            final String APIKEY = "MYAPI";
            final String URL = "http://localhost:8089/v2/discovery/events?apikey=" + APIKEY;
            final String readyUrl = URL + "&what=" + name;
            final RestTemplate restTemplate = new RestTemplate();
            final EventsResponse eventResponse = restTemplate.getForObject(readyUrl, EventsResponse.class);

            System.err.println("seatwave>>>" + eventResponse.getEvents().size());

            for (final Event event : eventResponse.getEvents()) {
                System.out.println("EventID: " + event.getId());
            }
        } catch (final Exception ex) {
            ex.printStackTrace();
        }

        // ---------- stops fake API server ------    
        wireMockServer.stop();
        // ---------------------------------------
    }
}

Output:

seatwave>>>2
EventID: 948040
EventID: 987509

Some reading about JAXB and collections: http://blog.bdoughan.com/2010/09/jaxb-collection-properties.html (NB: not my blog)


Versions used:

  • spring-web: 4.0.5.RELEASE
  • jaxb-api: 2.2.1
  • wiremock: 1.57
  • I tried that but stilll has same issue will try wiremock. – Daniel Newtown Sep 27 '15 at 11:23
  • I did add some comment (added / removed), I also completed your truncated xml (the posted one is invalid). This works so if you don't get it to work with your server, you should get some exception from `restTemplate` –  Sep 27 '15 at 11:47
  • Do you know of any alternative to WireMock? – Daniel Newtown Sep 28 '15 at 03:55
  • Alternative to do what, I don't have access to your API server so I did mock it, you have to use the real thing (url `http://api-sandbox.seatwave.com/v2/discovery/events...`). –  Sep 28 '15 at 05:40
  • I mean any other library similar to wiremock to mock? – Daniel Newtown Sep 28 '15 at 06:22
  • I don't know, why do you need that? –  Sep 28 '15 at 09:26
  • I tried your code, thats weird it does not work for me. Do you mind I give you the complete response and you test it in your code. – Daniel Newtown Sep 28 '15 at 09:32
  • 2
    I did upload a small project [here](https://github.com/Regisc/so32806530), you can hack it the way you want (response is in `src/main/resources/response.xml`). –  Sep 28 '15 at 11:49
  • Thanks for the code, it works but the response that I receive from server does not work. I think the reason is the response starts with '' not header of xml. – Daniel Newtown Oct 25 '15 at 05:23
  • @DanielNewtown That's not the problem, I got another sample response from the seatwave (with the XML start you mentioned) and RC's code still works. – approxiblue Oct 25 '15 at 19:18
  • @DanielNewtown Post the XML response you get, stack traces, etc. Can't help you with no details. – approxiblue Oct 26 '15 at 04:41
1

I was able to get Spring's RestTemplate to work with SeatWave's API

Here is a working example on github:https://github.com/cosbor11/seatwave-spring-client-example

Here are the Steps:

  1. Enter the following GET url into a browser:

    http://api-sandbox.seatwave.com/v2/discovery/events?apikey=4739E4694D0E482A92C9D0B478D83934&what=music

  2. View the source and copy paste the xml into a xsd generator.
  3. Generate the xsd with Russian Doll Style selected.
  4. Paste the generated content into a new file located some where like here: ${home}/Desktop/schema.xsd.
  5. Remove the first line if it looks like this: <?xml version="1.0" encoding="utf-16"?>
  6. Create a binding.xml file, that looks like this:

    <jaxb:bindings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" version="2.1">
        <jaxb:globalBindings localScoping="toplevel"/>
    </jaxb:bindings>
    
  7. Create a src file: mkdir src.
  8. Generate the Java Jaxb classes into that folder using XJC like this:

    xjc -b ~/Desktop/binding.xml -d src -p com.yourcompany ~/Desktop/schema.xsd

  9. Make sure you copy the generated classes and package structure into your build path.
  10. Also, in you build path, create a class with a main method that uses your RestTemplate:

    public static void main(String args[])
    {
        try
        {
    
            String name = "music";
            final String APIKEY = "4739E4694D0E482A92C9D0B478D83934"; //http://api-sandbox.seatwave.com/v2/discovery/events?apikey=4739E4694D0E482A92C9D0B478D83934&what=music
            final String URL = "http://api-sandbox.seatwave.com/v2/discovery/events?apikey=" + APIKEY;
            String readyUrl = URL + "&what=" + name;
            RestTemplate restTemplate = new RestTemplate();
            EventsResponse eventResponse = restTemplate.getForObject(readyUrl, EventsResponse.class);
    
            System.err.println("seatwave>>>" + eventResponse.getEvents().getEvent().size());
        }
        catch (NullPointerException e)
        {
            e.printStackTrace();
        }
    }
    
  11. Compile that class and run the main method. In this example you should get 50 records as the size. Notice that even if you change the name variable to something that returns an empty set, there will not be a NullPointerExeption.

Here is what the generated JAXB classes look like:

EventResponse.java:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "status",
    "paging",
    "events"
})
@XmlRootElement(name = "EventsResponse")
public class EventsResponse {

    @XmlElement(name = "Status", required = true)
    protected Status status;
    @XmlElement(name = "Paging", required = true)
    protected Paging paging;
    @XmlElement(name = "Events", required = true)
    protected Events events;

    //getters & setters

Events.java:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "event"
})
public class Events {

    @XmlElement(name = "Event", required = true)
    protected List<Event> event;

    public List<Event> getEvent() {
        if (event == null) {
            event = new ArrayList<Event>();
        }
        return this.event;
    }

}

Event.java:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "id",
    "date",
    "eventGroupName",
    "venueName",
    "town",
    "country",
    "ticketCount",
    "currency",
    "minPrice",
    "swURL",
    "eventGroupImageURL",
    "layoutId",
    "eventGroupId",
    "venueId",
    "swSellURL"
})
public class Event {

    @XmlElement(name = "Id")
    protected int id;
    @XmlElement(name = "Date", required = true)
    @XmlSchemaType(name = "dateTime")
    protected XMLGregorianCalendar date;
    @XmlElement(name = "EventGroupName", required = true)
    protected String eventGroupName;
    @XmlElement(name = "VenueName", required = true)
    protected String venueName;
    @XmlElement(name = "Town", required = true)
    protected String town;
    @XmlElement(name = "Country", required = true)
    protected String country;
    @XmlElement(name = "TicketCount")
    protected int ticketCount;
    @XmlElement(name = "Currency", required = true)
    protected String currency;
    @XmlElement(name = "MinPrice", required = true)
    protected BigDecimal minPrice;
    @XmlElement(name = "SwURL", required = true)
    protected String swURL;
    @XmlElement(name = "EventGroupImageURL", required = true)
    protected String eventGroupImageURL;
    @XmlElement(name = "LayoutId")
    protected int layoutId;
    @XmlElement(name = "EventGroupId")
    protected int eventGroupId;
    @XmlElement(name = "VenueId")
    protected int venueId;
    @XmlElement(name = "SwSellURL", required = true)
    protected String swSellURL;

    //getter & setters

Notes:

  • If you are using maven, there are some nifty tools to generate the jaxb classes into your generated-sources folder automatically. I recommend cxf-xjc-plugin.

  • Notice that Events#getEvent() method returns a new List if the event property is null.

  • The binding.xml file is handy for customizing the way your jaxb is generated, if you play around with it I bet you can figure out how to get the API classes to be interacted with in a more intuitive way. For example in you main class you could get the size by calling eventResponse.getEvents().size() instead of eventResponse.getEvents().getEvent().size().

cosbor11
  • 14,709
  • 10
  • 54
  • 69
0
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class EventsResponse {

    @XmlElementWrapper
    @XmlElement(name="event")
    private List<Event> events;

}

and the Events class can be removed.

D-rk
  • 5,513
  • 1
  • 37
  • 55