I have configured my WebService like this:
applicationContext:
<sws:annotation-driven />
<bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping" >
<property name="interceptors">
<list>
<bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"/>
</list>
</property>
Note: the Interceptor is loaded on startup, but doesn´t write anything, if a request is coming in.
I have a class PersonServiceImpl with the method addPersonRequest(). Everything works , if i am using org.dom4j.Element as method parameter;
@Endpoint
public class PersonServiceImpl {
@PayloadRoot(namespace = "http://www.example.org/person/schema", localPart = "AddPersonRequest")
@ResponsePayload
public AddPersonRequest addPersonRequest(@RequestPayload Element element) {
System.out.println(element.asXML());
Person response = new Person();
response.setId(2);
response.setFirstName("Mad");
response.setLastName("Mike");
return response;
}
}
But if i change my method parameters like shown below (so auto-marshalling of spring-ws should be used) the request.getFirstName() prints null. (JAXB2 is on classpath).
The Person-class is annotated with @XMLType and @XMLRootElement.
Note: The marshalling works fine.
@Endpoint
public class PersonServiceImpl {
@PayloadRoot(namespace = "http://www.example.org/person/schema", localPart = "AddPersonRequest")
@ResponsePayload
public AddPersonRequest addPersonRequest(@RequestPayload Person request, SoapHeader header) {
System.out.println(header.getName());
System.out.println(request.getFirstName());
Person response = new Person();
response.setId(2);
response.setFirstName("Mad");
response.setLastName("Mike");
return response;
}
}
Person.java:
@XmlType
@XmlRootElement(namespace="http://www.example.org/person/schema", name="Person")
public class Person implements Serializable {
private int id;
private String firstName;
private String lastName;
@XmlElement
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
@XmlElement
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@XmlAttribute
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
Test-Request sent via soapUI (generated from wsdl):
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sch="http://www.example.org/person/schema">
<soapenv:Header/>
<soapenv:Body>
<sch:AddPersonRequest>
<sch:Person sch:Id="1">
<sch:FirstName>firstname</sch:FirstName>
<sch:LastName>lastname</sch:LastName>
</sch:Person>
</sch:AddPersonRequest>
</soapenv:Body>
</soapenv:Envelope>
I'm not sure if you still need an answer, reading your latest comment. I'm a bit confused with your request and response payload. They seem to be switched. Anyway, that's hard to say without the Person class.
I've dealt with similar issues before though and those were solved by adding JAXBElement<> around the actual class. Like this snippet:
@PayloadRoot(
localPart = "PutOrganisationUnitRequest",
namespace = DEFAULT_NAMESPACE
)
@ResponsePayload public JAXBElement<Response> putOrganisationUnits (
@RequestPayload JAXBElement<PutOrganisationUnitRequest> organisations,
MessageContext messageContext) {
One other thing you can check is the namespaces in your jaxb class and in your endpoint definition.