Minimal spring ws (2.4.0) endpoint with xml payload

929 views Asked by At

I have a specific need for a SOAP endpoint. We use spring ws 2.4.0 framework at my organization.

What we really need is an endpoint that gets the SOAP message itself and returns a String. The message payload is XML data. All we need to do can be accomplished using the MessageContext object. We have no need for unmarshalled XML or such.

I've been doing some experiments but always end up with the following error:

 No adapter for endpoint [public java.lang.String org.company.endpoint.MyEndpoint.receiveSOAP(org.springframework.ws.context.MessageContext) throws java.lang.Exception]: Is your endpoint annotated with @Endpoint, or does it implement a supported interface like MessageHandler or PayloadEndpoint?

I probably have a ton of unnecessary configurations messing up my Spring ws framework right now. So any ideas how I can do this with minimal configuration:

  • receive SOAP with XML payload
  • SOAP message caught in Endpoint method
  • do my thing with messageContext parameter
  • return String (XML payload will do fine too)

Preferably skipping XML->POJO conversion, since the payload XML is huge

1

There are 1 answers

1
Kristiaan On BEST ANSWER

You can achieve this by using the DomPoxMessageFactory and a simple implementation of MessageEndpoint you write yourself. Like this:

@Override
public void invoke(MessageContext messageContext) throws Exception {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    messageContext.getRequest().writeTo(out);
    String message = out.toString();
    ...
}

Your spring configuration would contain:

<bean id="messageReceiver" class="com.yourcompany.MessageReceiver"/>

<bean id="messageFactory" class="org.springframework.ws.pox.dom.DomPoxMessageFactory">
</bean>

<!-- Register PayloadRootAnnotationMethodEndpointMapping -->
<bean class="org.springframework.ws.server.endpoint.mapping.SimpleMethodEndpointMapping">
    <property name="interceptors">
        <list>
            <ref bean="loggingInterceptor"/>
        </list>
    </property>
    <property name="defaultEndpoint" ref="fileReceiver"/>
    <property name="endpoints">
        <list>
            <ref bean="fileReceiver"/>
        </list>
    </property>
</bean>

<bean id="endpointAdapter" class="org.springframework.ws.server.endpoint.adapter.MessageEndpointAdapter"/>

<bean id="loggingInterceptor" class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor">
</bean>

<bean id="handlerAdapter" class="org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter">
    <property name="messageFactory" ref="messageFactory"/>
</bean>

<bean id="wsdlName" class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition">
    <property name="schema" ref="schema"/>
    <property name="portTypeName" value="MyInterface"/>
    <property name="locationUri" value="/ws/somepath/"/>
    <property name="targetNamespace" value="http://test.yourcompany.com/" />
    <property name="createSoap12Binding" value="true" />
    <property name="createSoap11Binding" value="false" />

</bean>

<bean id="schema" class="org.springframework.xml.xsd.SimpleXsdSchema">
    <property name="xsd" value="WEB-INF/schema.xsd"/>
</bean>

The message string you obtain in your endpoint would contain the whole XML, so including the SOAP envelope and such. If you want only the message body, do

messageContext.getRequest().getPayloadSource()

and you wil get a DOM Source for the payload in which you can look up the node containing the message content. (First child node is the envelope, the child node at index 3 of that node is the body.)