Sessions with CXF and Spring

The end goal is to be able to have sessions available for CXF webservice endpoints. This is achieved with the normal spring session operations, ie scopes. It does not involve WS-Addressing or any other transferrable mechanism, so is not a Grid solution, but does suit simple use cases.

The key is ensuring you have BOTH spring listeners in your web.xml.

  1. ContextLoaderListener? for locating the correct class to serve the request
  2. RequestContextListener? for providing sessions

Then, in your spring file you will need to specify a scope on the session beans, and probably use an aop:scoped-proxy.

FYI this worked fine with a Python ZSI 2.0 client.

web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  
        <context-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>WEB-INF/beans.xml</param-value>
        </context-param>
        <listener>
                <listener-class>
                        org.springframework.web.context.request.RequestContextListener
                </listener-class>
        </listener>
        <listener>
                <listener-class>
                        org.springframework.web.context.ContextLoaderListener
                </listener-class>
        </listener>

        <servlet>
                <servlet-name>CXFServlet</servlet-name>
                <display-name>CXF Servlet</display-name>
                <servlet-class>
                        org.apache.cxf.transport.servlet.CXFServlet
                </servlet-class>
                <load-on-startup>1</load-on-startup>
        </servlet>

        <servlet-mapping>
                <servlet-name>CXFServlet</servlet-name>
                <url-pattern>/*</url-pattern>
        </servlet-mapping>
</web-app>

beans.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:jaxws="http://cxf.apache.org/jaxws"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:cxf="http://cxf.apache.org/core"
        xmlns:wsa="http://cxf.apache.org/bindings/soap"
        xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd">
        <import resource="classpath:META-INF/cxf/cxf.xml" />
        <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
        <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
        
        <cxf:bus>
                <cxf:features>
                        <bean class="org.apache.cxf.feature.LoggingFeature"/>
                </cxf:features>
        </cxf:bus>
        
        <jaxws:endpoint id="helloWorld" implementor="#wsImpl"
                address="/HelloWorld" />
        <bean name="wsImpl" class="demo.spring.HelloWorldImpl" scope="session">
                <aop:scoped-proxy />
        </bean>
</beans>

Python

from HelloWorldImplService_services import *

loc = HelloWorldImplServiceLocator()
port = loc.getHello_PortType(url="http://localhost:8080/HelloWorld")
print port.sayHello(sayHello())
print port.sayHello(sayHello('nigel'))
print port.sayHello(sayHello('russell'))

References

 http://www.nabble.com/Share-object-in-request-scope-on-ws-server-td14611572.html

 http://static.springframework.org/spring/docs/2.0.x/reference/beans.html#beans-factory-scopes-other-web-configuration