aspose file tools*
The moose likes Web Services and the fly likes question about stateful webservice Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » Web Services
Bookmark "question about stateful webservice" Watch "question about stateful webservice" New topic
Author

question about stateful webservice

zb cong
Ranch Hand

Joined: Jan 14, 2002
Posts: 416
hello
who can tell me where i can find the tutorial about stateful webservice,or how can i keep the session status in the webservice?
Lasse Koskela
author
Sheriff

Joined: Jan 23, 2002
Posts: 11962
    
    5
You need to implement session handling yourself. I.e. you have to pass some kind of session ID with each service call and have the service implementation take care of loading/storing the session state into some persistence store (memory, disk, database).


Author of Test Driven (2007) and Effective Unit Testing (2013) [Blog] [HowToAskQuestionsOnJavaRanch]
zb cong
Ranch Hand

Joined: Jan 14, 2002
Posts: 416
thanks
could you tell me where i can the code sample.
otherwise,see following link:
http://newsgroups.borland.com/cgi-bin/dnewsweb?cmd=article&group=borland.public.jbuilder.webservices&item=639&utag=
Lasse Koskela
author
Sheriff

Joined: Jan 23, 2002
Posts: 11962
    
    5
I'm afraid I don't have a code sample at hand.
I wasn't aware of Axis' session scope parameters (probably because it's a proprietary extension - WSDL spec doesn't even contain the word "session").
zb cong
Ranch Hand

Joined: Jan 14, 2002
Posts: 416
thanks i use jbuilder8+axis+weblogic7 to test the stateful webservice,my code as following: ________________________________________________________________________________________
1 the javabean that is publish as webservice:
package test; import org.apache.axis.MessageContext; import org.apache.axis.session.*;
public class TestService {
int count=0;
public TestService() { }
public int count(){
Session session=MessageContext.getCurrentContext().getSession();
Integer cnt;
if((cnt=(Integer)session.get("count"))!=null){ count=cnt.intValue();
}
int c=++count; session.set("count",new Integer(c));
return c;
}
}
_________________________________________________________________________________________
2 my "deploy.wsdd" file:
<?xml version="1.0" encoding="UTF-8"?> <deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:ns="http://test" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="TestService" provider="java:RPC">
<parameter name="className" value="test.TestService"/>
<parameter name="allowedMethods" value="*"/> <parameter name="scope" value="Session"/>

</service>
</deployment> ________________________________________________________________________________________

3 my test client:
public class Client {
public Client() { }
public static void main(String[] args) {
try {
String endpoint ="http://localhost:7001/testservice/services/TestService";
Service service = new Service(); service.setMaintainSession(true);
Call call = (Call) service.createCall();
call.setTargetEndpointAddress(new java.net.URL(endpoint));
call.setOperationName(new QName( "http://localhost:7001/testservice/services/TestService", "count"));
Integer ret1 = (Integer) call.invoke(new Object[] {});
System.out.println("************************" + ret1 +"*********************************"); Integer ret2 = (Integer) call.invoke(new Object[] {});
System.out.println("************************" + ret1 +"*********************************");
}
catch (Exception e) {
System.err.println(e.toString());
}
}
} _________________________________________________________________________________________
after i execute the "client.class",the output as:
************************1********************************* ************************1*********************************
as you can see the status can't be keep,what i want is:
************************1********************************* ************************2*********************************

help please,thanks again!
Lasse Koskela
author
Sheriff

Joined: Jan 23, 2002
Posts: 11962
    
    5
Your problem is that you're not making the two calls within the same session - you are just sending two independent SOAP requests, which are then processed within two different sessions (each being closed immediately once the response has been sent).
You need to pass some parameter with which the MDB can fetch session data from a database of some sort.
For example:
zb cong
Ranch Hand

Joined: Jan 14, 2002
Posts: 416
thanks
do you mean that i must manipulate the session status MANUALLY?--creating a table(including session id and stateful data) in a database such as oracle to keep the status,to every request from the client side,i must query the table to retrieve the data matching the session id?
where and how generate can i the session id,it seem that it is generated from the client side.
i wonder if the webservice container provide the graceful and transparent way to keep the session status(the servlet container can provide such way).
otherwise,i find that the axis provide some session method as you can see from my code,but i don't know how to use them?
could you help me?
Lasse Koskela
author
Sheriff

Joined: Jan 23, 2002
Posts: 11962
    
    5
First, I apologize for not reading your code thoroughly enough... I see that you're using Axis' MessageContext class - my previous post was written with the assumption that you were talking about the EJB MessageContext. Sorry about that.
So, with Axis you don't need to implement the session stuff manually - you can use the MessageContext.getSession(). The thing is that you should change the client code somehow to use the same session for both requests. Unfortunately, I don't know how to do that.
[ April 28, 2003: Message edited by: Lasse Koskela ]
zb cong
Ranch Hand

Joined: Jan 14, 2002
Posts: 416
sorry it is my fault.see following code snippet:
..........
..........
Integer ret1 = (Integer) call.invoke(new Object[] {});
System.out.println("************************" + ret1 +"*********************************"); Integer ret2 = (Integer) call.invoke(new Object[] {});
System.out.println("************************" + ret1 +"*********************************");

modify it as following:
...............
...............
Integer ret1 = (Integer) call.invoke(new Object[] {});
System.out.println("************************" + ret1 +"*********************************"); Integer ret2 = (Integer) call.invoke(new Object[] {});
System.out.println("************************" + ret2 +"*********************************");
and the stateful java bean should look like:

public class TestService {
int count=0;
public TestService() { }
public int count(){
return ++count;
}
}

you don't need any "MessageContext" within it,then it works!
Lasse Koskela
author
Sheriff

Joined: Jan 23, 2002
Posts: 11962
    
    5
Originally posted by zb cong:
...you don't need any "MessageContext" within it,then it works!

...as long as you can count on the Web Service container to create only one instance of your class...
Lasse Koskela
author
Sheriff

Joined: Jan 23, 2002
Posts: 11962
    
    5
Umm... Do you need to keep the state of the service itself or the state of one client's sequence of service invocations? It you need to have separate counters for each client session, then you need to do something else. Otherwise, the member variable should do (you don't have "sessions" at all). However, you might consider moving the counter into a static variable as a quick-fix for the potential several-instances-of-my-web-service problem.
zb cong
Ranch Hand

Joined: Jan 14, 2002
Posts: 416
no i don't agree with you.if you want to keep the user information(such as "username" and "password" or some other session related variable),you can add variables accordingly in your java bean,then keep trace of the variables,my sample is only a demo.yes,if you want to count the client side invocation count,you should use the global static variables.
my program is the prototype for both of them.
otherwise,the "MessageContext" provided by axis can do this too i think,it is something like that of "Session context" in servlet container,but till now,i haven't used the "MessageContext".in my recent project,i always use the stateless webservices,only one of them need to keep the session information,but i keep it in the client side(that is a console application by vc#)manually,i think i should try to use the "MessageContext" in my next project.
Lasse Koskela
author
Sheriff

Joined: Jan 23, 2002
Posts: 11962
    
    5
Originally posted by zb cong:
no i don't agree with you.if you want to keep the user information(such as "username" and "password" or some other session related variable),you can add variables accordingly in your java bean,then keep trace of the variables,my sample is only a demo.yes,if you want to count the client side invocation count,you should use the global static variables.
my program is the prototype for both of them.

What exactly are we disagreeing? Which JavaBean you are talking about? I think we are thinking about the same things with different wordings...
Ramesh Nagappan
Author
Ranch Hand

Joined: May 06, 2003
Posts: 159
Originally posted by zb cong:
hello
who can tell me where i can find the tutorial about stateful webservice,or how can i keep the session status in the webservice?

In general, Web services standards does not mandate maintaining session state. But it is up to the Provider implementation to handle them.
In Sun JWSDP, JAX-RPC allows to save session state "Cookies" "URL Rewriting" "SSL Session" both on client-side and server-side environment.


Ramesh Nagappan CISSP<br />Co-Author of "Core Security Patterns"<br />nramesh@post.harvard.edu<br /><a href="http://www.coresecuritypatterns.com" target="_blank" rel="nofollow">www.coresecuritypatterns.com</a>
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: question about stateful webservice