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=&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&affid=&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=&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&affid=&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=&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&affid=&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=&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&affid=&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:
Ingrese la siguiente URL GET en un navegador:
- Ver la fuente y copiar pegar el xml en un generador xsd .
- Genera el xsd con
Russian Doll Styleseleccionado. - Pegue el contenido generado en un nuevo archivo ubicado en algún lugar como aquí:
${home}/Desktop/schema.xsd. - Quite la primera línea si se ve así:
<?xml version="1.0" encoding="utf-16"?> 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>- Crea un archivo src:
mkdir src. 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- Asegúrese de copiar las clases generadas y la estructura del paquete en su ruta de compilación.
Además, en tu ruta de creación, crea una clase con un método
mainque 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(); } }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 denamea algo que devuelve un conjunto vacío, no habrá unaNullPointerExeption.
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-sourcesautomáticamente. Recomiendo cxf-xjc-plugin .Observe que
Events#getEvent()métodoEvents#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 deeventResponse.getEvents().getEvent().size().