UnmarshallingFailureException:JAXB解组异常;嵌套异常是javax.xml.bind.UnmarshalException

时间:2015-08-24 11:56:24

标签: java spring webservice-client

我正在尝试发送SOAP请求并通过WebServiceTemplate接收响应,但我收到以下异常:

WSDL是here

SEVERE: Servlet.service() for servlet [bb] in context with path [/Bb] threw 
exception [Request processing failed; nested exception is 
org.springframework.oxm.UnmarshallingFailureException: JAXB unmarshalling 
exception; nested exception is javax.xml.bind.UnmarshalException: unexpected 
element (uri:"http://ticketmaster.productserve.com/v2/soap.php", 
local:"findEventsResponse"). Expected elements are <{}findEvents>,<{}request>,
<{}sortTicket>] with root cause

请求

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso({Request.class})
public class FindEvents {
    @XmlElement
    private Request request;

           getter / setter
}


@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso({SortTicket.class})
public class Request {
    @XmlElement
    private String apiKey;
    @XmlElement
    private String country;
    @XmlElement
    private int resultsPerPage;
    @XmlElement
    private int currentPage;
    @XmlElement(name = "Sort")
    private SortTicket sort;
    @XmlElement
    private String[] filters;
    @XmlElement
    private String updatedSince;

           getters / setters
}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class SortTicket {
    @XmlElement
    private String field;
    @XmlElement
    private String order;

           getters / setters
}

响应

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso({Return.class})
public class FindEventsResponse {
    @XmlElement
    private Return returnResult;

           getters / setters
}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso({Details.class,Results.class})
public class Return {
    @XmlElement
    private Details details;
    @XmlElement
    private Results results;

           getters / setters
}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Details {
    @XmlElement
    private int totalResults;
    @XmlElement
    private int totalPages;
    @XmlElement
    private int currentPage;
    @XmlElement
    private int resultsPerPage;

    getters / setters
}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso({ Artist.class, Venue.class })
public class Results {
    @XmlElement
    private long eventId;
    @XmlElement
    private String ticketmasterEventId;
    @XmlElement
    private String status;
    @XmlElement
    private String name;
    @XmlElement
    private String url;
    @XmlElement
    private String eventDate;
    @XmlElement
    private String onSaleDate;
    @XmlElement
    private String preSaleDate;
    @XmlElement
    private int categoyId;
    @XmlElement
    private String parentCategory;
    @XmlElement
    private int parentCategoryId;
    @XmlElement
    private Double minPrice;
    @XmlElement
    private Double maxPrice;
    @XmlElement(name = "Artists")
    private Artist artist;
    @XmlElement
    private Venue venue;

     getters / setters
}


@XmlRootElement(name = "Artists")
@XmlAccessorType(XmlAccessType.FIELD)
public class Artist {
    @XmlElement
    private long artistId;
    @XmlElement
    private long ticketMasterArtistId;
    @XmlElement
    private String name;
    @XmlElement
    private String url;
    @XmlElement
    private String imageUrl;
    @XmlElement
    private String category;
    @XmlElement
    private int categoryId;
    @XmlElement
    private String parentCategory;
    @XmlElement
    private int parentCategoryId;

           getters / setters
}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Venue {
    @XmlElement
    private long venueId;
    @XmlElement
    private long ticketmasterVenueId;
    @XmlElement
    private String name;
    @XmlElement
    private String street;
    @XmlElement
    private String city;
    @XmlElement
    private String country;
    @XmlElement
    private String postcode;
    @XmlElement
    private String url;
    @XmlElement
    private String imageUrl;
    @XmlElement
    private String state;

    getters / setters
}

配置如下

<oxm:jaxb2-marshaller id="marshaller">
        <oxm:class-to-be-bound name="com.bb.tickets.ticketmaster.FindEvents"/>
    </oxm:jaxb2-marshaller>

    <bean id="webServiceTemplate" 
        class="org.springframework.ws.client.core.WebServiceTemplate">
        <property name="marshaller" ref="marshaller" />
        <property name="unmarshaller" ref="marshaller" />
        <property name="defaultUri"
            value="http://ticketmaster.productserve.com/v2/soap.php" />

    </bean>

发送请求和接收响应的代码

SortTicket sortTicket = new SortTicket();
Request request = new Request();
request.setApiKey("APIKEY");
request.setCountry("UK");
FindEvents findEvents = new FindEvents();
findEvents.setRequest(request);
FindEventsResponse response = (FindEventsResponse) 
webServiceTemplate.marshalSendAndReceive(findEvents);
System.err.println("response:"+ 
response.getReturnResult().getDetails().getCurrentPage());  

1 个答案:

答案 0 :(得分:1)

从堆栈跟踪中,我了解到JAX-B收到类型为FindEventsResponse findEventsResponse 以进行编组,但它需要一个FindEvents对象。

问题出在你的弹簧配置中。你只告诉Spring,FindEvents类应该绑定到你的编组。您还需要使用 classesToBeBound 属性添加FindEventsResponse类:

<oxm:jaxb2-marshaller id="marshaller">
    <property name="classesToBeBound">
        <list>
            <value>com.bb.tickets.ticketmaster.FindEvents</value>
            <value>com.bb.tickets.ticketmaster.FindEventsResponse</value>
        </list>
    </property>
</oxm:jaxb2-marshaller>

您还可以使用 packageToScan 属性绑定包,请检查此question

希望能做到。

[编辑]:如果它不起作用,只需尝试:

<oxm:jaxb2-marshaller id="marshaller">
    <oxm:class-to-be-bound name="com.bb.tickets.ticketmaster.FindEvents"/>
    <oxm:class-to-be-bound name="com.bb.tickets.ticketmaster.FindEventsResponse"/>
</oxm:jaxb2-marshaller>