tutorial services example ejemplo java spring rest jaxb spring-web

services - web service java spring



RestTemplate no puede llenar el objeto (3)

Tengo el siguiente código para enviar una solicitud y recibir una respuesta, parece que todo está configurado pero el código está devolviendo NullPointerException .

No estoy seguro de lo que falta. Imprimí la variable readyURL que tiene la dirección URL correcta. El stackTrace no ofrece mucho.

Código

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

Excepción

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)

Resultado de la muestra

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

Actualizar

Agregué este código justo después de la línea restTemplate.getForObject, pero no se mostrará nada en la consola.

if(eventResponse == null) { System.err.println("it is null"); }else{ System.err.println("message:>>"+eventResponse.getStatus().getMessage()); }


@XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class EventsResponse { @XmlElementWrapper @XmlElement(name="event") private List<Event> events; }

y la clase Eventos se puede eliminar.


Hice que tu código funcionara mediante algunos cambios de asignación:

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

luego lo probé usando 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(); // --------------------------------------- } }

Salida:

seatwave>>>2 EventID: 948040 EventID: 987509

Algunas lecturas sobre JAXB y colecciones: http://blog.bdoughan.com/2010/09/jaxb-collection-properties.html (NB: not my blog)

Versiones utilizadas:

  • spring-web: 4.0.5.RELEASE
  • jaxb-api: 2.2.1
  • wiremock: 1.57

Pude hacer que Spring''s RestTemplate trabajara con la API de SeatWave

Aquí hay un ejemplo de trabajo en github: https://github.com/cosbor11/seatwave-spring-client-example

Aquí están los pasos:

  1. Ingrese la siguiente URL GET en un navegador:

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

  2. Ver la fuente y copiar pegar el xml en un generador xsd .
  3. Genera el xsd con Russian Doll Style seleccionado.
  4. Pegue el contenido generado en un nuevo archivo ubicado en algún lugar como aquí: ${home}/Desktop/schema.xsd .
  5. Quite la primera línea si se ve así: <?xml version="1.0" encoding="utf-16"?>
  6. Cree un archivo binding.xml , que se vea así:

    <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. Crea un archivo src: mkdir src .
  8. Genere las clases Java Jaxb en esa carpeta usando XJC de esta manera:

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

  9. Asegúrese de copiar las clases generadas y la estructura del paquete en su ruta de compilación.
  10. Además, en tu ruta de creación, crea una clase con un método main que use tu 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. Compila esa clase y ejecuta el método main . En este ejemplo, debe obtener 50 registros del tamaño. Tenga en cuenta que incluso si cambia la variable de name a algo que devuelve un conjunto vacío, no habrá una NullPointerExeption .

Aquí es cómo se ven las clases JAXB generadas:

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

Notas:

  • Si está utilizando maven, hay algunas herramientas ingeniosas para generar las clases de jaxb en su carpeta de generated-sources automáticamente. Recomiendo cxf-xjc-plugin .

  • Observe que Events#getEvent() método Events#getEvent() devuelve una nueva lista si la propiedad del evento es nula.

  • El archivo binding.xml es útil para personalizar la forma en que se genera su jaxb. Si juegas con él, apuesto a que puedes averiguar cómo interactuar con las clases de API de una manera más intuitiva. Por ejemplo, en su clase principal puede obtener el tamaño llamando a eventResponse.getEvents().size() lugar de eventResponse.getEvents().getEvent().size() .