我试图通过我的页面来保持SessionBean的范围,为此,我从这里开始学习一些教程,实际上,我正在尝试通过ExternalContext获取会话,如下面的代码:
public class LoginFilter implements Filter{
ProfileBean pBean = new ProfileBean();
ActiveUserModel activeUserModel;
ExternalContext tmpEC;
Map sMap;
public void destroy() {}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
tmpEC = FacesContext.getCurrentInstance().getExternalContext();
sMap = tmpEC.getSessionMap();
activeUserModel = (ActiveUserModel) sMap.get("ActiveUserModel");
String username = SecurityAssociation.getPrincipal().getName();
if(activeUserModel.getUsername() == null)
{
try {
pBean.consultaProfile(username);
} catch (SQLException e) {
e.printStackTrace();
} catch (NamingException e) {
e.printStackTrace();
}
}else{
}
filterChain.doFilter(servletRequest, servletResponse);
}
public void init(FilterConfig filterConfig) throws ServletException {}
}
在这一行if(activeUserModel.getUsername()== null),我得到一个java.lang.NullPointerException,因为我没有实例化bean,但即使我实例化它,也没有用。
有什么问题?
答案 0 :(得分:5)
您正在获取NPE,因为You cannot obtain a FacesContext
object位于JSF工件的上下文之外(@ManagedBean
,@FacesConverter
,@FacesComponent
,PhaseListener
等),相对于JSF请求。因此,sMap
将在该行
不确定您为什么选择首先通过FacesContext
寻找会话。您可以轻松地执行此操作:
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//Get a hold of the http request
HttpServletRequest req = (HttpServletRequest)request;
//Access the HttpSession associated with the request
HttpSession session = req.getSession(false);
//Take what you want from the session
activeUserModel = (ActiveUserModel) session.getAttribute("ActiveUserModel");
String username = SecurityAssociation.getPrincipal().getName();
if(activeUserModel.getUsername() == null) {
try {
pBean.consultaProfile(username);
} catch (SQLException e) {
e.printStackTrace();
} catch (NamingException e) {
e.printStackTrace();
}
}else{
}
filterChain.doFilter(servletRequest, servletResponse);
}
JSF中的SessionScope
就像您已经知道的那样是HttpSession
的外观。因此,您可以轻松地进入基本HttpSession
并提取所有@SessionScoped
变量,而不是您正在探索的环形交叉路口FacesContext
答案 1 :(得分:1)
如果会话范围bean为null,则表示尚未为会话创建它。这可能发生在新会话的第一次请求期间。您需要自己创建它并将其放在会话范围内。 JSF将在会话的剩余部分中重用它。
你抓住会话范围bean的方式有点笨拙。您将从JSF的引擎盖下获取原始Servlet API。您也可以使用ExternalContext#getSessionMap()
来管理会话属性。
Map<String, Object> sessionMap = externalContext.getSessionMap();
LoginBean loginBean = (LoginBean) sessionMap.get("loginBean");
if (loginBean == null) {
loginBean = new LoginBean();
sessionMap.put("loginBean", loginBean);
}
// ...
请注意,您不应将bean声明为PhaseListener的实例变量。在整个应用程序的生命周期中只有一个PhaseListener实例,因此所有实例变量都将在所有请求/会话之间共享。换句话说:它不是线程安全的。