Results 1 to 6 of 6

Thread: Converting an Axis2 web service to Spring-WS

  1. #1
    Join Date
    Jan 2009
    Posts
    29

    Default 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. #2
    Join Date
    Jan 2009
    Posts
    29

    Default

    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 at 02:39 PM.

  3. #3

    Default

    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 Abedrabbo

    My Twitter
    My Blog

  4. #4
    Join Date
    Jan 2009
    Posts
    29

    Default

    Quote 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>

  5. #5

    Default

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

    My Twitter
    My Blog

  6. #6
    Join Date
    Jan 2009
    Posts
    29

    Default

    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?

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •