By Scott Balmos
[posted by Jack Vaughan]
Stateful SOAP, EJB3, and SFSB sessions… oh my! A thorny issue with SOAP, with the requisite multiple implementations, has been how to track client sessions. Put more simply, the SOAP equivalent of HTTP sessions… How do you turn an inherently stateless protocol into a stateful one?
I know of at least three common ways that sessions are tracked in Java SOAP services, and all are not so much a part of SOAP as they are tricks in whatever implementing stacks are used.
The first way is probably the most common, and takes advantage of the fact that almost all SOAP usage has been through HTTP. This is through the roundabout retrieval of the underlying SOAP endpoint servlet’s HttpSession object. Afterwards, adding session variables such as a session ID or other info is just like a regular servlet. However, this is “out-of-band” of SOAP, and relies on your SOAP stack being nice enough to allow you to touch the underlying HTTP request framework.
The second method is interesting, and I know it is used by Salesforce.com. Once a SOAP client logs in, or starts a session, the SOAP endpoint that all subsequent requests should be sent to is reset to a session-specific SOAP stack. With Salesforce, I have yet to tell whether this is a full separate virtual machine, or a virtualized URL into the same SOAP request cluster. I surmise it may be the former, given their documentation. More on this manner in a moment.
The third way I intentionally left for last, and actually melds SOAP with REST in a way, where an underlying session management system provides a session ID or token, which is then passed in every subsequent SOAP method call. This manner is a bit more in-band with SOAP, and at least theoretically decouples the session management from the SOAP request format. In the Java world, where this manner usually entails a direct SOAP > SLSB EJB endpoint, this has been commonly hacked by making the “session” a single stateful session bean, while the SOAP endpoint is a stateless session bean facade. The “session ID/token” is the serialized stateful bean’s Handle, which the stateless endpoint turns around and deserializes into the stateful session bean object.
This final manner was all well and good in EJB 2.1 . But EJB3 specifically deprecates the Handle, relying on directly saving the SFSB reference to a suitable location. Sure, you can regain access to the Handle if you reimplement the EJB 2.1 interfaces and methods. But that’s just ugly and dirties up that nice, clean code with the pretty @Stateful and @Stateless annotations.
As it is, I have not found a good method for tracking sessions that is purely “SOAP in-band”, not taking advantage of the underlying request framework. I have seen some references to making session-tracking part of WS-Addressing. Indeed, one promising part of Glassfish and JAX-WS is the JAX-WS-specific @Stateful @WebService @Addressing annotation set one would put on a servlet endpoint. True, this method relies on an HTTP-only SOAP endpoint. But it uses WS-Addressing underneath to automagically redirect all client requests to a session-specific endpoint URL. It’s sort of like how JSP, PHP, etc all have the option of embedding the session ID in the URL if cookies aren’t available.
Actually, I have to do some testing, but the above annotations may work on a non-HTTP endpoint. SOAP/TCP’s on the horizon, there’s still the message-passing SOAP/JMS & SOAP/SMTP. There’s obviously some other potential black holes, and requires the SOAP stacks support WS-Addressing and its ilk (WS-DeathStar from TSSJS lives on!). But this method looks the most promising, considering JAX-WS is being adopted by not only Glassfish, but also WebLogic 10.
If you’ve been doing stateful SOAP in your apps, I’d be interested to hear about it, as I’m sure others would. Personally, I’m doing the serialized Handle hack with EJB3, but I’m quickly trying to get away from it. I’ll be converting my SOAP endpoint code, which thankfully is in a separate Web Service Tier module, to the new JAX-WS method within the next month. How about you?