user497087
user497087

Reputation: 1591

Accessing Spring Session scoped Proxy Beans

I'm developing a web-app using Struts 2 with a Spring 3 backend. I'm using Spring aop:proxy beans to handle my session beans rather than the Struts 2 SessionAware interface. Everything was working fine until I have an Action that is running under the Struts ExecAndWait interceptor. Because this interceptor in effect runs my action under a seperate thread, when I come to try and access my proxied session bean, I get a BeanCreationException/IllegalStateException. Is there another "spring way" that I can get hold of my session beans in this scenario?

Regards

Upvotes: 5

Views: 2044

Answers (3)

invariant
invariant

Reputation: 8900

You can use ,RequestContextHolder(Holder class to expose the web request in the form of a thread-bound RequestAttributes object.) to make session scoped proxy beans available to child threads.

Define a custom ExecuteAndWait Interceptor and in doIntercept method use the following static method from RequestContextHolder

public static void setRequestAttributes(RequestAttributes attributes,boolean inheritable)

Bind the given RequestAttributes to the current thread.

Parameters: attributes - the RequestAttributes to expose, or null to reset the thread-bound context inheritable - whether to expose the RequestAttributes as inheritable for child threads (using an InheritableThreadLocal)

Sample Code

public class CustomExecuteAndWaitInterceptor extends ExecuteAndWaitInterceptor {

    @Override
    protected String doIntercept(ActionInvocation actionInvocation) throws Exception {
         RequestAttributes requestAtteiAttributes = RequestContextHolder.getRequestAttributes(); //Return the RequestAttributes currently bound to the thread. 
         RequestContextHolder.setRequestAttributes(requestAtteiAttributes, true);
       //do something else if you want ..
        return super.doIntercept(actionInvocation);

    }   
}

Upvotes: 0

Tomasz Nurkiewicz
Tomasz Nurkiewicz

Reputation: 340963

From Execute and Wait Interceptor documentation

Important: Because the action will be running in a seperate thread, you can't use ActionContext because it is a ThreadLocal. This means if you need to access, for example, session data, you need to implement SessionAware rather than calling ActionContext.getSession().

The problem with session scoped-beans is that they depend on thread-local attributes set by RequestContextListener or RequestContextFilter. But the latter allows you to set very interesting threadContextInheritable flag...

If your ExecAndWait interceptor creates new thread per every request it serves, inheritable thread local should propagate session scoped beans to child threads. However if Struts uses thread pool (more likely, thou I haven't used Struts2 for ages) to serve this requests, this will have very unexpected and dangerous results. You might experiment with this flag, maybe it will do the trick.

Upvotes: 3

Quaternion
Quaternion

Reputation: 10458

You can Implement your own ExecAndWait interceptor using Spring. You can also delegate the management/creation of this action to Spring. For the later the details are in the S2 spring plugin documentation.

Upvotes: 0

Related Questions