我正在尝试在JSF2支持bean(或servlet)中检索由自定义Tomcat Valve设置的值。我无法看到如何执行此操作,但我找不到使用Google的任何示例。
背景:在我的JSF2 Web应用程序中,我需要为每个用户添加一个时区属性。实现此目的的最简单方法是将时区下拉列表添加到用户配置文件页面,以便每个用户都可以选择适当的时区。但是,这可以自动化,因为bit of JavaScript in the browser能够自动计算时区。
所以我在我的Tomcat登录页面上添加了一个新参数,该页面提供了这个值,Web应用程序可以在登录时捕获该值。 Tomcat表单身份验证机制负责处理登录页面(通过HTTP POST到j_security_check)。我实现了一个Java EE Servlet Filter来捕获它,但是Tomcat的登录机制绕过了Filters,所以这段代码永远不会看到POST到j_security_check。
我现在已经实现了Tomcat Valve,我可以成功地将POST捕获到j_security_check。在代码中我提取时区值并把它放在哪里?
据我所知,阀门(必须放在TOMCAT_HOME / lib中)与我的常规JSF2代码有不同的类加载器。这意味着我无法从我的JSF2代码访问阀门的任何静态成员。
受到标准Tomcat阀门源代码的启发,我在阀门内尝试了这个:
final org.apache.catalina.Session session = request.getSessionInternal(true);
session.setNote("com.conexa.timezoneOffset", timezoneOffset);
但是,在我的JSF2托管bean中,我无法获得对org.apache.catalina.Session的引用。
此代码返回一个StandardSessionFacade类型的对象,它不允许我访问org.apache.catalina.Session。
。FacesContext.getCurrentInstance()getExternalContext()的getSession(假);
在调试模式下运行,我已经能够找到org.apache.catalina.Session,但'notes'字段实际上是空的。
我还认为Tomcat可能会使用一个会话进行登录,然后在之后创建一个新会话(可能与Session Fixation Protection相关)。如果情况确实如此,我认为这个问题会更复杂。
任何Tomcat大师都有什么好主意吗?普通servlet的解决方案也是可以接受的,因为我确信我能够适应它。
答案 0 :(得分:3)
好的,明白了!
在阀门代码中:
final HttpSession session = request.getSession(true);
session.setAttribute("timezoneOffset", timezoneOffset);
在JSF2代码中:
final ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
final String timezoneOffsetStr = "" + externalContext.getSessionMap().get("timezoneOffset");