我有一个Stateful Session Bean
,它保存我的登录会话,一个JSF Session Bean
和一个Servlet Filter
。
我想做的是阻止未登录的用户访问我的页面,所以我做了一个过滤器。
doFilter()
是这样的:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
String path = req.getRequestURI().substring(req.getContextPath().length());
System.out.println(userManager.isLogged());
if (userManager.isLogged() || path.equals("/") || path.equals("/index.xhtml") || path.startsWith(ResourceHandler.RESOURCE_IDENTIFIER) || path.startsWith("/resources/") || path.startsWith("/admin") || path.equals("/admin/login.xhtml")) {
chain.doFilter(request, response);
} else {
request.getRequestDispatcher("/error.xhtml").forward(request, response);
}
}
其中userManager
为 :
private UserManagerLocal lookupUserManagerLocal() {
try {
Context c = new InitialContext();
return (UserManagerLocal) c.lookup("java:global/UNILIFE/UNILIFE-ejb/UserManager!ejb.UserManagerLocal");
} catch (NamingException ne) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
throw new RuntimeException(ne);
}
}
现在,System.out.println(userManager.isLogged());
打印总是假的,而#{loginBean.logged}
打印的是真的。
请注意,loginBean.logged
只是
public boolean isLogged() {
return userManager.isLogged();
}
并且,在我的托管 Bean 中,userManager
检索
@EJB
private UserManagerLocal userManager;
似乎 servlet 不采用与 JSF 托管 Bean 相同的 SFSB。
我做错了什么?
编辑:新代码
奴役
UserManagerLocal userManager = lookupUserManagerLocal();
private UserManagerLocal lookupUserManagerLocal() {
try {
Context c = new InitialContext();
UserManagerLocal userM = (UserManagerLocal) c.lookup("java:global/UNILIFE/UNILIFE-ejb/UserManager!ejb.UserManagerLocal");
HttpServletRequest req = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
req.setAttribute("userManager", userM);
return userM;
} catch (NamingException ne) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
throw new RuntimeException(ne);
}
}
JSF 豆
@PostConstruct
public void init(){
HttpServletRequest req = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
userManager = (UserManagerLocal) req.getSession().getAttribute("userManager");
}
每次查找有状态会话 Bean 时,您都在创建一个唯一的实例,因此 isLogs 大概返回默认字段值。 您需要以某种方式将有状态会话 Bean 实例存储在 HttpSession 中,并从过滤器中检索它。 我缺乏 JSF 专业知识,所以我不知道是否有一种方便的方法来共享有状态会话 Bean 实例,或者您是否需要手动将 JSF Bean 链接到有状态 Bean。
每个 JNDI 查找都会返回一个新的 bean 句柄。因此,您在调用方法时获取默认值,丢弃以前的活动。您需要保存该引用(HttpSession)以对其进行进一步操作,如其他帖子中所述。
下面是在 JSF Bean 中访问会话的示例代码。
HttpServletRequest req = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
从请求中,您可以获取会话,然后放入其中。
session.setAttribute("userManager", userManager);
现在在过滤器中,您可以从请求中检索 bean。此外,相应地修改代码。