-
1. Re: Who can help with design challenge to get data from Sess
enterprisejavabones Sep 25, 2004 9:51 AM (in response to ebende)Hi Evert,
If i understand correctly, you need your servlet to access the result of the calculation produced by your session bean.
First of all, is your SessionBean stateful or stateless?
Secondly, i don't really understand thisIn some way the data in the session bean should be associated with a user session of the servlet.
Are you saying that the data must be obtained while the HttpSession is active?
If so, here's what i think mite help you.
Create a JNDI bindable JavaBean (lets call it CalcContext) type of object which your session bean has access to (can instantiate). Once your session bean completes its calculations it can create an instance of the CalcContext and bind it into to the JNDI tree. If there is already a CalcContext bound, you can use the Context.rebind method to update the JNDI tree with a CalcContext that contains the most updated data.
Your servlet then can lookup your CaclContext (even if its on a diff server or VM) using JNDI.
To do this you'll need:
A CalcContext interface which extends java.rmi.Remote. In this interface define a Setter/Gettter method(s) to store/retrieve your calculation values.public interface CalcContext extends java.rmi.Remote { public static final String JNDI_NAME = "myapp/CalcData"; public void setCalcDataTotalValue(int value); public void setCalcDataLineItems(Hashtable lineItems); public int getCalcDataTotalValue(); public Hashtable getCalcDataLineItems(); }
A CalcContextImpl class which extends java.rmi.server.UnicastRemoteObject and implements your CalcContext interface. This class will have the attributes to store your calc results and implementations of your setter/getter's defined in CalcContext.public class CalcContextImpl { private int calcTotal; private Hashtable lineItems; public void setCalcDataTotalValue(int total) { this.calcTotal = total; } public void setCalcDataLineItems(Hashtable lineitems) { this.lineItems = lineitems; } public int getCalcDataTotalValue() { return this.total; } public Hashtable getCalcDataLineItems() { return this.lineItems; } }
Your session bean when completing its calculation will then need a method something like:public boolean bindResult(Object resultData) { InitialContext ic = new InitialContext(); CalcContextImpl cci = new CalcContextImpl(); // ------- // code that sets the value of your CalcContextImpl attributes // ------- Remote stub = UnicastRemoteObject.toStub(cci); try { ic.rebind(CalcContext.JNDI_NAME); return true; } catch (Exception e) { //exception handling code return false; } }
finally your servlet when it wants to obtain the data will simply lookup the object in the JNDI tree, narrow it to the type of Object it is supposed to be and use it. This would be something likepublic void doPost(HttpServletRequest req, HttpServletResponse res) { InitialContext ic = new InitialContext(); Object obj = ic.lookup(CalcContext.JNDI_NAME); CalcContext cc = (CalcContext)java.rmi.PortableRemoteObject.narrow(obj, CalcContext.class); cc.getCalcDataTotalValue(); cc.getCalcDataLineItems(); }
Guess that should bout help, if i understood your question correctly :) -
2. Re: Who can help with design challenge to get data from Sess
ebende Sep 27, 2004 3:47 AM (in response to ebende)Prem,
thank you very much for your clear and comprehensive answer. I'm going to study it. For now, I have some questions.
1.
A. Since more than 1 user might do the calculation, the calculational results should be stored in a something like a HashMap() with the sessionID as key I suppose. Once the session is ending, a method in a listener servlet (that listens whether a session ends) should remove the calculational data belonging to that session.
B. The alternative is to create a JNDI name for every session, consisting of the sessionID to make it unique (eg myapp/CalcData7af648af647af341). But this seems not very desirable to me.
Would you also do that like that? I mean option 1A. Or does it make a difference whether you are using stateful or stateless Session Beans. I'm not sure whether I undstand the JNDI binding correctly.
2. What is the code lineRemote stub = UnicastRemoteObject.toStub(cci);
doing? The stub object is not being used after this code line.
Hope you can also give an answer to these questions.
Again thanks,
Evert
http://212.203.14.69/topsolar/cgi-bin/climatetop50/cgi-bin/topsites.cgi?action=in&id=69 -
3. Re: Who can help with design challenge to get data from Sess
enterprisejavabones Sep 28, 2004 8:20 AM (in response to ebende)Hi Evert,
For question 1, if i were you, i would implpement it using your suggestion 1A. I sure would not want to bind an Object to JNDI for each user session that is active. As such, I would probably change the CalcContextImpl class to be something likepublic class CalcContextImpl private HashMap calcData; public void setCalcDataLineItems(String userSession, Object calcs) { synchronized(this) { if (calcData.containsKey(userSession) //you need to create this exception throw new SessionAlreadyActiveException("Session ID......"); else calcData.put(userSession, calcs); } } public Object removeCalcDataForSession(String userSession) { synchronize(this) { if (!calcData.containsKey(userSession) //again you need to create this throw new NoSuchUserSessionExceptoin("blah blah blah"); else return calcData.remove(userSession); } } }
This way, when a user requests the calculations to be done, they are computed and stored in a CalcContextImpl object and bound to the defined JNDI namespace (in this case --> myapp/CalcData). An important point to note, you have to ensure that you synchronize your access to the HashMap.
When a user session is ending, your listener servlet can lookup the CalcContextImpl from JNDI and remove the calc data for the particular user session.Or does it make a difference whether you are using stateful or stateless Session Beans. I'm not sure whether I undstand the JNDI binding correctly.
If you are storing the data in a "beanified" object and binding it to JNDI, then its probably better to use a Stateless Session Bean. If you are binding the Object (CalcContext in this case), then it dosen't make a diff whether you are using Stateless/Stateful (tho i'd recommend Stateless as they're easier to code)
For Question 2:
There was actually an error in my example. This code is wrong.Remote stub = UnicastRemoteObject.toStub(cci); try { ic.rebind(CalcContext.JNDI_NAME); return true; } catch (Exception e) { //exception handling code return false; }
Should actually be this:Remote stub = UnicastRemoteObject.toStub(cci); try { ic.rebind(CalcContext.JNDI_NAME, stub); return true; } catch (Exception e) { //exception handling code return false; }
In this case, you are creating a Remote object from your CalcContextImpl class which can be bound into JNDI.
Another typo i realised is this:public class CalcContextImpl { private int calcTotal; private Hashtable lineItems; ......
It should actually bepublic class CalcContextImpl implements CalcContext { private int calcTotal; private Hashtable lineItems;
Hope that helps,
G'luck
Prem -
4. Re: Who can help with design challenge to get data from Sess
ebende Sep 30, 2004 3:05 AM (in response to ebende)Prem,
many thanks again. It's clear. If you need help, let me know. Though I'm not sure if I can help you.
Evert
http://212.203.14.69/topsolar/cgi-bin/climatetop50/cgi-bin/topsites.cgi?action=in&id=69