Question

I'm trying to retrieve a value set by a custom Tomcat Valve in a JSF2 backing bean (or servlet). I can't see how to do this and I can't find any examples using Google.

BACKGROUND: In my JSF2 web app, I'm required to add a timezone attribute to each user. The easiest way of implementing this would be to add a timezone drop-down to the users profile page, so that each user can choose their appropriate timezone. However this could be automated because a bit of JavaScript in the browser is able to automatically calculate the timezone.

So I've put a new parameter on my Tomcat login page which supplies this value, which the web app can capture at login time. The Tomcat form authentication mechanism is responsible for processing the login page (via an HTTP POST to j_security_check). I implemented a Java EE Servlet Filter to catch this, but Tomcat's login mechanism circumvents Filters, so this code would never see the POST to j_security_check.

I've now implemented a Tomcat Valve and I can successfully catch the POST to j_security_check. In the code I extract the timezone value and put it... where?

I understand that the valve (which has to be placed in TOMCAT_HOME/lib) has a different classloader to my regular JSF2 code. This means that I can't access any static members of the valve from my JSF2 code.

So inspired by the source code for the standard Tomcat valves, I have tried this within the valve:

final org.apache.catalina.Session session = request.getSessionInternal(true);
session.setNote("com.conexa.timezoneOffset", timezoneOffset);

However, in my JSF2 managed beans I am unable to get a reference to the org.apache.catalina.Session.

This code returns an object of type StandardSessionFacade which doesn't let me get at the org.apache.catalina.Session.

FacesContext.getCurrentInstance().getExternalContext().getSession(false);

Running in debug mode, I've been able to find the org.apache.catalina.Session, but the 'notes' field is actually empty.

I also think that Tomcat may use one session for login and then create a new session afterwards (possibly related to Session Fixation Protection). If this is indeed the case, the problem would be compounded I think.

Do any Tomcat gurus have any bright ideas? A solution for plain servlets would also be acceptable because I'm sure I'd be able to adapt it.

Was it helpful?

Solution

Ok, got it!

In the valve code:

final HttpSession session = request.getSession(true);
session.setAttribute("timezoneOffset", timezoneOffset);

In the JSF2 code:

final ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
final String timezoneOffsetStr = "" + externalContext.getSessionMap().get("timezoneOffset");
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top