Jaxb2Marshaller and primitive types
Is it possible to create a web service operation using primitive or basic Java types when using the Jaxb2Marschaller in spring-ws? For example a method looking like this:
@Override
@PayloadRoot(localPart = "AddTaskRequest", namespace = "http://example.com/examplews/")
public long addTask(final Task task) throws AddTaskFault {
// do something
return 0;
}
I am using the maven jaxws plugin to generate the interface and model classes from my WSDL. When I try to call the webservice I get the following error:
java.lang.IllegalStateException: No adapter for endpoint [...]: Does your endpoint implement a supported interface like MessageHandler or PayloadEndpoint
I found out that if I change the method to that:
@Override
@PayloadRoot(localPart = "AddTaskRequest", namespace = "http://example.com/examplews/")
public JAXBElement<Long> addTask(final JAXBElement<Task> task) throws AddTaskFault {
final ObjectFactory objectFactory = new ObjectFactory();
return objectFactory.createAddTaskResponse(0L);
}
I am able to call it - but this signature is not compatible with the interface generated by the maven jaxws plugin.
What can I do to configure either spring-ws to be able to use the first kind of implementation or t开发者_JAVA技巧o tell maven jaxws plugin to generate the second variant of the interface?
UPDATE: My relevant spring-ws config entries look like that:
<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="contextPath" value="com.example.examplews" />
</bean>
<bean class="org.springframework.ws.server.endpoint.adapter.GenericMarshallingMethodEndpointAdapter">
<constructor-arg ref="marshaller" />
</bean>
<bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping">
<property name="order" value="1" />
</bean>
When Spring-WS is trying to match an EndpointAdapter
to an Endpoint
, it checks that all of the parameters of the endpoint method, plus its return value, are types known to the Jaxb2Marshaller
, and long
will not. Conceptually, this makes sense, since JAXB would have no idea how to turn a long
into XML without more information (which is where JAXBElement
comes in).
You should realise that Spring-WS is not a JAX-WS implementation, and makes no pretense to be. You can't really expect to take JAX-WS-generated artifacts and expect them just to work in Spring_WS, although in many cases Spring-WS is flexible enough to deal with it.
Here is everything relevant in my config as I can't really tell what you could change, they are rather different and it has been a year and a half since i did this.
<bean id="schemaCollection"
class="org.springframework.xml.xsd.commons.CommonsXsdSchemaCollection">
<property name="xsds" value="/my.xsd" />
<property name="inline" value="true" />
</bean>
<bean id="marshallingEndpoint"
class="....EndpointImpl">
</bean>
<oxm:jaxb2-marshaller id="marshaller" contextPath=".....schema" />
<bean id="annotationMapping" class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping">
<property name="interceptors">
<list>
<bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor" />
<bean class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor">
<property name="xsdSchemaCollection"
ref="schemaCollection" />
<property name="validateRequest" value="true" />
<property name="validateResponse" value="true" />
</bean>
</list>
</property>
<property name="order" value="1" />
</bean>
<sws:marshalling-endpoints />
Hope it helps in some way. The Endpoint class had @Endpoint, the methods @PayloadRoot. They didn't return long, but I didn't have to wrap my class in the JAXBElement either.
[edit] namespaces
xmlns:oxm="http://www.springframework.org/schema/oxm"
xmlns:sws="http://www.springframework.org/schema/web-services"
xsi:schemaLocation="
http://www.springframework.org/schema/oxm
http://www.springframework.org/schema/oxm/spring-oxm-1.5.xsd">
精彩评论