PDA

View Full Version : How to use session scope variables in webservice


wade
07-16-2007, 11:32 AM
I'm trying to put a User object in the session using web service, so after the client login, he needn't pass the user information any more.
I found the object has a property scope, and 'session' is an available value.
but after I set to scope="session" and reference it in the WebServiceExporter as the following:
<object id="CurrentUser" type="com.newgarman.domain.User, Newgarman.Service" scope="session">
</object>
<object id="demoWebTarget" type="com.newgarman.webservice.impl.DemoWebService">
<property name="DemoService">
<ref object="demoService"/>
</property>
<property name="CurrentUser">
<ref object="CurrentUser"/>
</property>
</object>

<object id="demoWebService" type="Spring.Web.Services.WebServiceExporter, Spring.Web">
<property name="TargetName" value="demoWebTarget" />
<property name="Namespace" value="http://webservice/WebServices" />
<property name="Description" value="Spring Demo Web Services" />

<property name="MemberAttributes">
<dictionary>
<entry key="*">
<object type="System.Web.Services.WebMethodAttribute, System.Web.Services">
<property name="EnableSession" value="True"/>
</object>
</entry>
</dictionary>
</property>
</object>

it throws an exception that:
'session'-scoped objects require SessionState to be enabled.
Line 234: if (sessionCache == null)
Line 235: {
Line 236: throw ConfigurationUtils.CreateConfigurationException(
Line 237: "'session'-scoped objects require SessionState to be enabled.");
Line 238: }

Is there anything else I need to config or change? anyone can help? thanks in advance.

Bruno Baia
07-16-2007, 04:27 PM
Hi,
This should be enough :

<object type="System.Web.Services.WebMethodAttribute, System.Web.Services">
<property name="EnableSession" value="True"/>
</object>


As you can see, scope should not be used with WebServiceExporter.


Hth,
Bruno

wade
07-17-2007, 03:16 AM
Hi, thanks for your reply.

I have enabled the session inside the WebServiceExporter, and I need to use CurrentUser object in DemoWebService which is a general class, so I added a property CurrentUser as the following:

public class DemoWebService : IDemoWebService
{
private IDemoService demoService;
public IDemoService DemoService
{
get
{
return demoService;
}
set
{
demoService = value;
}
}
private User currentUser;

public User CurrentUser
{
get { return currentUser; }
set { currentUser = value; }
}

public Demo GetDemoById(int demo_id)
{
Demo demo = new Demo();

if(CurrentUser == null){
demo.UserName = "New user";
CurrentUser = new User(); // generate a new User object
CurrentUser.UserLoginName = "new user in spring";
}else{
demo.UserName = CurrentUser.UserLoginName;
}

return demo;
}
}

Here's my configuration, I added a CurrentUser reference in DemoWebService. I made it more clear to read.

<object id="CurrentUser" type="com.newgarman.domain.User, Newgarman.Service" scope="session">
</object>

<object id="demoWebTarget" type="com.newgarman.webservice.impl.DemoWebService ">
<property name="DemoService">
<ref object="demoService"/>
</property>
<property name="CurrentUser">
<ref object="CurrentUser"/>
</property>
</object>

<object id="demoWebService" type="Spring.Web.Services.WebServiceExporter, Spring.Web">
<property name="TargetName" value="demoWebTarget" />
<property name="Namespace" value="http://webservice/WebServices" />
<property name="Description" value="Spring Demo Web Services" />

<property name="MemberAttributes">
<dictionary>
<entry key="*">
<object type="System.Web.Services.WebMethodAttribute, System.Web.Services">
<property name="EnableSession" value="True"/>
</object>
</entry>
</dictionary>
</property>
</object>

Now it throws exception: 'session'-scoped objects require SessionState to be enabled.
And after I removed the CurrentUser reference in DemoWebService, there's no error, so I think maybe something need to do with the DemoWebService. But I didn't get any idea.

Then the question is how can I use the CurrentUser in my DemoWebService? thanks again.

wade
07-18-2007, 10:05 AM
Anyone can help me?

Can I use the session variable in web service using injection?
If yes, then how can I do that?
thanks.

wade
07-23-2007, 02:17 AM
Does this can't be done in spring?

Bruno Baia
07-26-2007, 02:10 AM
Hi,

Can you try to set lazy-init=true for 'CurrentUser' and 'demoWebTarget' definitions.

HTH,
Bruno

Erich Eichinger
07-31-2007, 07:05 AM
Hi,

Now it throws exception: 'session'-scoped objects require SessionState to be enabled.
And after I removed the CurrentUser reference in DemoWebService, there's no error, so I think maybe something need to do with the DemoWebService.

The problem here is that 'DemoWebService' is a singleton with implicit 'application' scope that gets created during container instantiation and 'CurrentUser' is of 'session' scope. This means you are injecting an object with a smaller lifetime into another with a larger lifetime. Furthermore during container instantiation there is no session available - but 'CurrentUser' is referenced, which causes the exception you are experiencing.

Then the question is how can I use the CurrentUser in my DemoWebService? thanks again.

You could make your DemoWebService 'IApplicationContextAware' (by implementing this interface) and obtain the 'CurrentUser' object from within your methods:

private IApplicationContext _applicationContext;
private string _currentUserObjectName;

void myServiceMethod()
{

CurrentUser user =
_applicationContext.GetObject( _currentUserObjectName );
}


If you want to avoid implementing IApplicationContextAware, you could also leverage AOP to obtain a 'CurrentUser' instance from the applicationContext and place it e.g. into HttpContext.Items where your service methods can obtain it from.

hope this helps,
Erich

wade
08-01-2007, 06:41 AM
Thanks for all, I Solved the problem by aop.
Now I'm storing the session level variable into httpsession instead of using a spring bean.

Now I'm using a IMethodInterceptor and inject it into a ProxyFactoryObject, then I can get the session in the advice, and that's just what I want since I can do any business logic there.

Thanks again. Spring.net is a great work.