PDA

View Full Version : Accessing the HttpSession within Spring?


JasonGabler
Aug 12th, 2007, 10:00 PM
I'm trying to emulate AppFuses' Constants.java gadget, where the members therein are available as Constants.VAR within Java code and in JSP's as <c:... value="...${VAR}..." .../>. I do not know how AppFuse does it, but I have got the outward functionality working well using reflection and HttpSession.setAttribute() to get Constants.java's member variables onto the HttpSession.

However, I have to initiate this configuration from the action which retrieves my app's top index page, to get an HttpRequest and so get a HttpSession from which I can run HttpSession.setAttribute(). I cannot seem to figure out is how to access the HttpSession from Spring so I can use a Spring bean and by pass my hokey action-based way of doing this.

Any ideas?


thanks,

Jason

Jörg Heinicke
Aug 13th, 2007, 10:04 PM
I don't know if it is a possible solution for you since I don't know exactly what you are trying to do (I don't know AppFuse and can't follow your explanations), but maybe session-scoped beans are a solution for you. In my last web project I had no need to access the session at all.

Joerg

JasonGabler
Aug 14th, 2007, 09:48 AM
I don't know if it is a possible solution for you since I don't know exactly what you are trying to do (I don't know AppFuse and can't follow your explanations), but maybe session-scoped beans are a solution for you. In my last web project I had no need to access the session at all.

Joerg

Thank for the reply, Joerg. I was trying out sessio-scoped beans and I wasn't not getting the desired result; perhaps I was doing something wrong? (I'll try again and if it does not work I'll post on this thread with some code)

To clear up what I am trying to do: I want to have a class with a bunch of "public static final String" member variables. These variables are accessible to entire application's Java code as global constants. I also run a small method on this class which uses reflection to find all of its member variable names and values and puts them onto the HttpSession. (I use reflection so that adding a variable to the glass does not also force me to somehow "register" the new variable for putting it on the session... you add the member variable, it automagically gets onto the sesion).

The problem, as I think you can see now, is my ability to gracefuly access the HttpSession...

JasonGabler
Aug 14th, 2007, 01:19 PM
OK, I believe know why scope="session" does not work for what I am trying to do.

This bean attribute relates an instance of the bean to a single session. Such an instance is only available to its related session and has the lifetime of the session, dying when the session dies. This bean attribute does nothing to add the bean as a session attribute... and that is what I want to do. Doh!

So, I still need a way to get the current HttpSession from within Spring...

pmularien
Aug 14th, 2007, 01:43 PM
Doesn't HttpServletRequest.getSession() work? The current HttpServletRequest is passed to the majority of *Controller methods.

JasonGabler
Aug 14th, 2007, 02:19 PM
Doesn't HttpServletRequest.getSession() work? The current HttpServletRequest is passed to the majority of *Controller methods.

Two issues on that: I am not using SpringMVC but Spring+Struts (so I have Actions, not Controllers). And, I do not want to do this within an Action. The purpose is to pull global constants onto the session that need to be simultaneously available to both the application (Java code) and the session (JSP). if I use an Action the values cannot be populated into the session attributes until a particular Action is run. This means someone could use a different action before the particular one and have no access to these constants. Things will break, NPEs, etc. Bad. I could put the session-attribute-populating routine into every action (say into my base action class), but that's just not the right way to do this. Ugly.

What I'd believe is the most elegant method is to have a session scope bean from Spring have access to the sessions attributes so it can run my reflective method and put its members on that list of attributes. The thought just gives me chills.

JasonGabler
Aug 14th, 2007, 03:05 PM
OK my next idea... scrap the HttpSession idea. This is probabaly the wrong way. Well, for the most part I have the right idea, but instead of using the HttpSession, I will try to use the SevletContext ... THIS is something Spring beans have access to via the ServletContextAware interface. It is also something JSP's have access to... providing I am right in thinking that the ServletContext and Application scope are the "same" thing...

This makes better design sense anyhow. If the constants I want to supply are global for the application, they should be available on an application scope, not recreated for every session. I'll reply again later to report on whether this works or not...

Jörg Heinicke
Aug 14th, 2007, 03:40 PM
Just for the record a potential solution for the session: What about a HttpSessionBindingListener (http://java.sun.com/products/servlet/2.2/javadoc/javax/servlet/http/HttpSessionBindingListener.html) then? This would be notified of every session that gets created and could register the variables.

ServletContext sounds indeed more reasonable. And it is indeed the application scope.

Joerg

DJViking
Aug 14th, 2007, 04:36 PM
JSP also have access to the HttpSession with the variable name session or through request.getSession(). Both will give you access to the session in JSP

JasonGabler
Aug 14th, 2007, 04:39 PM
Just for the record a potential solution for the session: What about a HttpSessionBindingListener (http://java.sun.com/products/servlet/2.2/javadoc/javax/servlet/http/HttpSessionBindingListener.html) then? This would be notified of every session that gets created and could register the variables.

ServletContext sounds indeed more reasonable. And it is indeed the application scope.

Joerg

So the ServletContext solution worked perfectly! I'm glad I figured it out before you mentioned HttpSessionBindingListener , otherwise I might not have done it the "righter" way ;)

as you say, for the record, then one would use HttpSessionBindingListener in this way, at least for what I had planned?


public MySpringBean implements HttpSessionBindingListener {
HttpSession session = null;
void valueBound(HttpSessionBindingEvent event) {
this. session = event.getSession();
}
void valueUnbound(HttpSessionBindingEvent event) {}

// from <bean name="mySpringBean" .... init-method="init"/>
public void init() {
for(each of some set of member variables) {
session.setAttribute(name, value);
}
}
}

Jörg Heinicke
Aug 14th, 2007, 06:22 PM
as you say, for the record, then one would use HttpSessionBindingListener in this way, at least for what I had planned?

No, you must not make the listener stateful (which you do with keeping the session in an instance variable). Why don't you execute the init() stuff in valueBound()? No Spring would be involved. Do you need it?

Joerg

JasonGabler
Aug 14th, 2007, 07:30 PM
No, you must not make the listener stateful (which you do with keeping the session in an instance variable). Why don't you execute the init() stuff in valueBound()? No Spring would be involved. Do you need it?

Joerg

Ah, gotcha. No, I don't need it anymore with my other solution. I was just curious though. This is great stuff. Thanks for sharing your knowledge and wisdom :)