Search code examples
spring-ws

@PayloadRoot value when using Objects and not schema xml


I'm using Objects as messages from client to service server. How should the endpoint be configured so that the service would be found? @PayloadRoot seems unfitting here because i don't use xml schema but Objects annotated with @XmlRootElement (i.e. Street)

my code:

the spring-ws-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:sws="http://www.springframework.org/schema/web-services"
   xmlns:oxm="http://www.springframework.org/schema/oxm"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
   http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd
   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
   http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd">

<context:component-scan base-package="com.coral.project.endpoints"/>

<sws:annotation-driven />

<sws:dynamic-wsdl id="test" portTypeName="TestCase" locationUri="/testService/"
                  targetNamespace="http://www.example.org/schemasDef/test/definitions">
    <sws:xsd location="/WEB-INF/schemasDef/test.xsd"/>
</sws:dynamic-wsdl>

<bean id="springWSClient" class="com.coral.project.endpoints.SpringWSClient">
    <property name="defaultUri" value="http://localhost:8080/parking/springServices/testService/"/>
    <property name="marshaller" ref="marshaller" />
    <property name="unmarshaller" ref="marshaller" />
</bean>

<oxm:jaxb2-marshaller id="marshaller">
    <oxm:class-to-be-bound name="com.coral.project.entity.Street"/>
</oxm:jaxb2-marshaller>
</beans>

the client:

public class SpringWSClient extends WebServiceGatewaySupport {

public void getSum() throws SOAPException, IOException, TransformerException {
    StreetDao streetDao = SpringUtils.getBean(StreetDao.class);
    Street street = streetDao.findById(1);

    getWebServiceTemplate().marshalSendAndReceive(street);

}
}

the endpoint:

@Endpoint
public class SpringWsEndpoint {

@Inject
private SpringWebService springWebService;

@PayloadRoot(localPart = "street", namespace = "http://blahblah")
@ResponsePayload
public Element handleTestRequest(@RequestPayload SAXSource testRequest) throws Exception {

    String fisrt = firstNum.valueOf(testRequest);
    String second = secondNum.valueOf(testRequest);

    String sum = springWebService.sum(Integer.parseInt(fisrt), Integer.parseInt(second)).toString();

    Element responseElement = new Element("TestRequest");
    Element sumElement = new Element("sum");
    sumElement.setText(sum);
    responseElement.setContent(sumElement);

    return responseElement;
}

}

Solution

  • Found out how to do it. Had to make several fixes. Most importantly @XmlRootElement name and namespace attributes are required in my case. So the working code is:

    test.xsd

    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
        xmlns:test="http://www.example.org/schemasDef/test/schemas" 
        elementFormDefault="qualified"
        targetNamespace="http://www.example.org/schemasDef/test/schemas">
    
        <xs:element name="TestRequest">
            <xs:complexType>
                <xs:all>
                    <xs:element name="firstNum" type="xs:integer" />
                    <xs:element name="secondNum" type="xs:integer" />
                    <xs:element name="sum" type="xs:integer" />
                </xs:all>
            </xs:complexType>
        </xs:element>
    
    </xs:schema>
    

    TestRequest.java

    package com.coral.project.entity;
    
    import javax.xml.bind.annotation.XmlRootElement;
    
    @XmlRootElement(name="TestRequest",namespace="http://www.example.org/schemasDef/test/schemas")
    public class TestRequest {
    
    private Integer firstNum;
    private Integer secondNum;
    private Integer sum;
    
    public Integer getFirstNum() {
        return firstNum;
    }
    public void setFirstNum(Integer firstNum) {
        this.firstNum = firstNum;
    }
    public Integer getSecondNum() {
        return secondNum;
    }
    public void setSecondNum(Integer secondNum) {
        this.secondNum = secondNum;
    }
    public Integer getSum() {
        return sum;
    }
    public void setSum(Integer sum) {
        this.sum = sum;
    }
    
    }
    

    spring-ws-servlet.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:sws="http://www.springframework.org/schema/web-services"
       xmlns:oxm="http://www.springframework.org/schema/oxm"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
       http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd">
    
    <context:component-scan base-package="com.coral.project.endpoints"/>
    
    <sws:annotation-driven marshaller="marshaller" unmarshaller="marshaller"/>
    
    <sws:dynamic-wsdl id="test" portTypeName="TestCase" locationUri="/testService/"
                      targetNamespace="http://www.example.org/schemasDef/test/definitions">
        <sws:xsd location="/WEB-INF/schemasDef/test.xsd"/>
    </sws:dynamic-wsdl>
    
    <bean id="springWSClient" class="com.coral.project.endpoints.SpringWSClient">
        <property name="defaultUri" value="http://localhost:8080/parking/springServices/testService"/>
        <property name="marshaller" ref="marshaller" />
        <property name="unmarshaller" ref="marshaller" />
    </bean>
    
    <oxm:jaxb2-marshaller id="marshaller">
        <oxm:class-to-be-bound name="com.coral.project.entity.TestRequest"/>
    </oxm:jaxb2-marshaller>
    </beans>
    

    SpringWsEndpoint.java

    package com.coral.project.endpoints;
    
    import javax.inject.Inject;
    
    import org.springframework.ws.server.endpoint.annotation.Endpoint;
    import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
    import org.springframework.ws.server.endpoint.annotation.RequestPayload;
    import org.springframework.ws.server.endpoint.annotation.ResponsePayload;
    
    import com.coral.project.entity.TestRequest;
    import com.coral.project.services.ifc.SpringWebService;
    
    @Endpoint
    public class SpringWsEndpoint {
    
    private static final String NAMESPACE_URI = "http://www.example.org/schemasDef/test/schemas";
    
    @Inject
    private SpringWebService springWebService;
    
    
    @PayloadRoot(namespace = NAMESPACE_URI, localPart = "TestRequest")
    @ResponsePayload
    public TestRequest handleTestRequestObj(@RequestPayload TestRequest testRequest) throws Exception {
    
        Integer sum = springWebService.sum(testRequest.getFirstNum(), testRequest.getSecondNum());
        testRequest.setSum(sum);
        return testRequest;
    
    }
    
    
    }
    

    SpringWsClient.java

    package com.coral.project.endpoints;
    
    import java.io.IOException;
    
    import javax.xml.soap.SOAPException;
    import javax.xml.transform.TransformerException;
    
    import org.springframework.ws.client.core.support.WebServiceGatewaySupport;
    
    import com.coral.project.entity.TestRequest;
    
    public class SpringWSClient extends WebServiceGatewaySupport {
    
    public TestRequest getTestRequest() throws SOAPException, IOException, TransformerException {
        TestRequest testRequest = new TestRequest();
        testRequest.setFirstNum(6);
        testRequest.setSecondNum(9);
    
        TestRequest testResponse = (TestRequest)getWebServiceTemplate().marshalSendAndReceive(testRequest);
        return testResponse;
    }
    }