Announcement Announcement Module
Collapse
No announcement yet.
Converting an Axis2 web service to Spring-WS Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Converting an Axis2 web service to Spring-WS

    Hello Spring Gurus,

    I have a need to convert an existing Axis2 web service to Spring-WS. Moreover, I need to do this without causing any changes to the clients - so this is a bit of "reverse" web service coding.

    Still, I thought "Simple! I have the contract (WSDL), as long as my Spring-WS web service adheres to the contract, all will be right with the world!". Easier said than done.

    So here is where I stand:

    I have a simple WSDL that was originally generated by Axis2.
    I implemented the web service in Spring-WS.
    I map urls of the type "/axis2/service/*" to the MessageDispatcherServlet so that existing clients can continue sending requests to the same url.

    What I noticed that my axis2 client is sending the message in the following format (neither of which looks compatible with PayloadRootQNameEndpointMapping or SoapActionEndpointMapping). The following is the http post as sent from the client, along with the response from the server:

    Code:
    POST /axis2/services/GeneralService HTTP/1.1
    Content-Type: application/soap+xml; charset=UTF-8; action="urn:getServerVersion"
    User-Agent: Axis2
    Host: 127.0.0.1:8080
    Transfer-Encoding: chunked
    
    93
    <?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><soapenv:Body /></soapenv:Envelope>"
    
    0
    
    
    
    HTTP/1.1 400 No Host matches server name 127.0.0.1
    Server: Apache-Coyote/1.1
    Transfer-Encoding: chunked
    Date: Fri, 30 Oct 2009 17:25:45 GMT
    Connection: close
    
    0
    As you can see in the request message, there is nothing in the SOAP:Body payload, and also no SOAP Action header. The action is defined as part of the Content-Type http header. What kind of EndpointMapping should be used to process this message?

    Thanks!

  • #2
    Forgot to post the WSDL. This WSDL was generated by axis2 and used by the axis2 client to generate the client stubs.

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
    	xmlns:axis2="http://general/" 
    	xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" 
    	xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" 
    	xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" 
    	xmlns:ns1="http://org.apache.axis2/xsd" 
    	xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" 
    	xmlns:ns="http://general/xsd/" 
    	xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    	xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
    	targetNamespace="http://general/">
        
        <wsdl:documentation>GeneralService</wsdl:documentation>
        <wsdl:types>
            <xs:schema attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://general/xsd/">
                <xs:element name="getServerVersionResponse">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element minOccurs="0" name="return" nillable="true" type="xs:string"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:schema>
        </wsdl:types>
        <wsdl:message name="getServerVersionRequest"/>
        <wsdl:message name="getServerVersionResponse">
            <wsdl:part name="parameters" element="ns:getServerVersionResponse"/>
        </wsdl:message>
        <wsdl:portType name="GeneralServicePortType">
            <wsdl:operation name="getServerVersion">
                <wsdl:input message="axis2:getServerVersionRequest" wsaw:Action="urn:getServerVersion"/>
                <wsdl:output message="axis2:getServerVersionResponse" wsaw:Action="urn:getServerVersionResponse"/>
            </wsdl:operation>
        </wsdl:portType>
        <wsdl:binding name="GeneralServiceSoap11Binding" type="axis2:GeneralServicePortType">
            <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
            <wsdl:operation name="getServerVersion">
                <soap:operation soapAction="urn:getServerVersion" style="document"/>
                <wsdl:input>
                    <soap:body use="literal"/>
                </wsdl:input>
                <wsdl:output>
                    <soap:body use="literal"/>
                </wsdl:output>
            </wsdl:operation>
        </wsdl:binding>
        <wsdl:binding name="GeneralServiceSoap12Binding" type="axis2:GeneralServicePortType">
            <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
            <wsdl:operation name="getServerVersion">
                <soap12:operation soapAction="urn:getServerVersion" style="document"/>
                <wsdl:input>
                    <soap12:body use="literal"/>
                </wsdl:input>
                <wsdl:output>
                    <soap12:body use="literal"/>
                </wsdl:output>
            </wsdl:operation>
        </wsdl:binding>
        <wsdl:binding name="GeneralServiceHttpBinding" type="axis2:GeneralServicePortType">
            <http:binding verb="POST"/>
            <wsdl:operation name="getServerVersion">
                <http:operation location="GeneralService/getServerVersion"/>
                <wsdl:input>
                    <mime:content type="text/xml" part="getServerVersion"/>
                </wsdl:input>
                <wsdl:output>
                    <mime:content type="text/xml" part="getServerVersion"/>
                </wsdl:output>
            </wsdl:operation>
        </wsdl:binding>
        <wsdl:service name="GeneralService">
            <wsdl:port name="GeneralServiceHttpSoap11Endpoint" binding="axis2:GeneralServiceSoap11Binding">
                <soap:address location="/axis2/services/GeneralService.GeneralServiceHttpSoap11Endpoint"/>
            </wsdl:port>
            <wsdl:port name="GeneralServiceHttpSoap12Endpoint" binding="axis2:GeneralServiceSoap12Binding">
                <soap12:address location="/axis2/services/GeneralService.GeneralServiceHttpSoap12Endpoint"/>
            </wsdl:port>
            <wsdl:port name="GeneralServiceHttpEndpoint" binding="axis2:GeneralServiceHttpBinding">
                <http:address location="/axis2/services/GeneralService.GeneralServiceHttpEndpoint"/>
            </wsdl:port>
        </wsdl:service>
    </wsdl:definitions>
    The web.xml:

    Code:
    <servlet>
    	<servlet-name>spring-ws</servlet-name>
    	<servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
    	<load-on-startup>2</load-on-startup>
    </servlet>
    
    <servlet-mapping>
    	<servlet-name>spring-ws</servlet-name>
    	<url-pattern>/axis2/services/*</url-pattern>
    </servlet-mapping>
    
    <servlet-mapping>
    	<servlet-name>spring-ws</servlet-name>
    	<url-pattern>/ws/*</url-pattern>
    </servlet-mapping>
    The spring-ws-servlet.xml. I have tried many different endpoint mappings but all seem to result in the HTTP 400 error.

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
    
    	<bean id="general" class="org.springframework.ws.wsdl.wsdl11.SimpleWsdl11Definition">
    		<constructor-arg value="/WEB-INF/wsdl/General.wsdl"/>
    	</bean>
    
    	<bean id="endpointMapping" class="org.springframework.ws.server.endpoint.mapping.UriEndpointMapping">
    		<property name="mappings">
    			<props>
    				<prop key="/axis2/services/GeneralService">getServerVersionEndpoint</prop>
    			</props>
    		</property>
    		<property name="interceptors">
    			<list>
    				<ref local="loggingInterceptor"/>
    			</list>
    		</property>
    	</bean>
    	    
    	<bean id="loggingInterceptor" class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor">
    		<description>
    		    This interceptor logs the message payload.
    		</description>
    	</bean>
    
    	<bean id="getServerVersionEndpoint" class="com.mycompany.ws.endpoints.GetServerVersionEndpoint">
    		<description>
    		    Returns the server version
    		</description>
    		<constructor-arg ref="generalManager"/>
    	</bean>
    
    </beans>
    Last edited by jporche; Oct 30th, 2009, 02:39 PM.

    Comment


    • #3
      From the request Content-Type, it seems your Axis service uses SOAP 1.2. I suggest you set your Spring-WS service to use SOAP 1.2 as well, then the soap action mapping should work.

      Comment


      • #4
        Originally posted by tareq View Post
        From the request Content-Type, it seems your Axis service uses SOAP 1.2. I suggest you set your Spring-WS service to use SOAP 1.2 as well, then the soap action mapping should work.
        Tareq,

        I modified my spring-ws-servlet.xml and added a message factory for SOAP 1.2, but I still get the 400 error from my web server. Is anything else required?

        Code:
        <bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">
        	<property name="soapVersion">
        		<util:constant static-field="org.springframework.ws.soap.SoapVersion.SOAP_12"/>
        	</property>
        </bean>
        
        <bean id="endpointMapping" class="org.springframework.ws.soap.server.endpoint.mapping.SoapActionEndpointMapping">
        	<property name="mappings">
        		<props>
        			<prop key="urn:getServerVersion">getServerVersionEndpoint</prop>
        		</props>
        	</property>
        	<property name="interceptors">
        		<list>
        			<ref local="loggingInterceptor"/>
        		</list>
        	</property>
        </bean>

        Comment


        • #5
          Is there any debug information or stack trace from the server side that could help us understand what's going on?

          Comment


          • #6
            Ok, I figured out why I was getting the 400 errors.. I was omitting my webapp context in the url sent by the axis2 client. Once I fixed this, I was able to get my Endpoint to handle the message.

            I still have one concern. The following are the HTTP headers from the response to GetServerVersion from Axis2:

            Code:
            HTTP/1.1 200 OK 
            HTTP/1.1 200 OK 
            Server: Apache-Coyote/1.1 
            Content-Type: application/soap+xml; action="urn:getServerVersionResponse";charset=UTF-8 
            Transfer-Encoding: chunked 
            Date: Mon, 02 Nov 2009 18:19:02 GMT
            And here is the response as sent from my Spring-WS endpoint:

            Code:
            HTTP/1.1 200 OK
            HTTP/1.1 200 OK
            Server: Apache-Coyote/1.1
            Accept: application/soap+xml, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
            SOAPAction: ""
            Content-Type: application/soap+xml;charset=utf-8
            Content-Length: 229
            Date: Mon, 02 Nov 2009 19:16:43 GMT
            As you can see, the Axis2 version includes the response message name in the Content-Type. The Spring-WS version omits this, and adds a blank SOAPAction header. Should this be a concern?

            Comment

            Working...
            X