|
|
||
Rama Pulavarthi's BlogMaintaining Session With JAX-WSPosted by ramapulavarthi on June 07, 2006 at 10:26 AM | Comments (8)Web Services are stateless by default because of the underlying HTTP protocol. The server processes each web service request as a new interaction even though it is from the same client. To have a knowledge about previous requests, Server would need to maintain state about the client through some sort. Maintaining state/session would have extra load on the client/server in terms of time and memory. Even then, sometimes stateful web services can be useful for conversational message exchange patterns, where multiple message exchanges are required between client and server. By default JAX-WS Web Services and Clients are stateless. When a client makes a request, the server responds and sets a cookie on the connection, if it participates in a session. But, the JAX-WS client ignores that cookie and the server treats subsequent requests as new interaction. When the session is enabled, JAX-WS client sends the same cookie with each subsequent request so that server can keep track of the client session. Lets start off with a simple Counter Web Service which tracks the user requests. Each time client calls getCounter(), the service returns the counter after incrementing by 1.
@WebService
public class Hello {
int counter = 0;
public int getCounter() {
// incorrect – not unique for each client session.
return counter++;
}
}
Enabling session support for your web service would require little effort on the server and client. Accessing Session on Server:After the service endpoint is instantiated, the runtime system is required to initialize the endpoint instance before any requests can be serviced. If you are familiar with JAX-RPC based Web Service, enabling session support would require the service to implement javax.xml.rpc.server.ServiceLifecycle interface and its lifecycle methods init() and destroy(). The JAX-RPC runtime would pass the ServletEndpointContext which gives access to the message context, session, servlet context associated with each method invocation. JAX-WS uses some handy annotations defined by Common Annotations for the Java Platform (JSR 250), to inject the Web Service context and declaring lifecycle methods. Web ServiceContext holds the context information pertaining to a request being served. You don’t need to implement javax.xml.rpc.server.ServiceLifecycle. With JAX-WS Web Service all you need to do is mark a field or method with @Resource. The type element MUST be either java.lang.Object (the default) or javax.xml.ws.WebServiceContext. If the former, then the resource will be injected into a field or a method. In this case, the type of the field or the type of the JavaBeans property defined by the method MUST be javax.xml.ws.WebServiceContext. From the WebServiceContext, message context pertaining to the the current request can be accessed. For more information on how message context can be used to share metadata is explained in this article. The following snippet from Hello Service shows the usage of annotations.
@WebService
public class Hello {
@Resource
private WebServiceContext wsContext;
public int getCounter(){
MessageContext mc = wsContext.getMessageContext();
HttpSession session = ((javax.servlet.http.HttpServletRequest)mc.get(MessageContext.SERVLET_REQUEST)).getSession();
// Get a session property "counter" from context
if (session == null)
throw new WebServiceException("No session in WebServiceContext");
Integer counter = (Integer)session.getAttribute("counter");
if (counter == null) {
counter = new Integer(0);
System.out.println("Starting the Session");
}
counter = new Integer(counter.intValue() + 1);
session.setAttribute("counter", counter);
return counter;
}
}
JSR-250 also defines annotations for lifecycle methods, @PostConstruct and @PreDestroy. These lifecycle annotations (methods) can be used for effectively managing memory resources. After the resource injection is done, methods marked with @PostConstruct (similar to init method in JAX-RPC) are invoked before servicing any requests. Similarly methods marked with @PreDestroy are invoked before the service is destroyed. Enabling Session on Client:Session can be maintained just by setting the property “MessageContext.SESSION_MAINTAIN_PROPERTY” to true in the request context of the proxy/dispatch instance. For more information about setting properties in request context refer to this article. Hello proxy = new HelloService().getHelloPort(); ((BindingProvider)proxy).getRequestContext().put(BindingProvider.SESSION_MAINTAIN_PROPERTY,true); int result = proxy.getCounter(); System.out.println(result); result = proxy.getCounter(); System.out.println(result); The above snippet from the HelloClient, prints 1 and 2 respectively.As shown above maintaining session with JAX-WS is easy. Bookmark blog post: CommentsComments are listed in date ascending order (oldest first) | Post Comment
| ||
|
|