在我的JSF应用程序中,有一个Filter
用于检查authenticati0n进程。身份验证失败时,过滤器会重定向到login.xhtml
。
如何从FacesMessage
将Filter
传递到我的登录页面?
虽然,我在下面使用,但不行。
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, message, null));
AuthenticationFilter.java
public class AuthenticationFilter implements Filter {
private FilterConfig config;
private ServletContext servletContext;
public void init(FilterConfig filterConfig) {
config = filterConfig;
servletContext = config.getServletContext();
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
HttpSession session = httpRequest.getSession();
User user = (User) session.getAttribute(Constants.LOGIN_USER);
if (user == null) {
...
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, message, null));
String loginView = httpRequest.getContextPath() + Constants.LOGIN_PAGE;
httpResponse.sendRedirect(loginView);
} else if (!user.getRole().equals(Role.SYSTEM_ADMINISTRATOR)) {
....
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, message, null));
String loginView = httpRequest.getContextPath() + Constants.LOGIN_PAGE;
httpResponse.sendRedirect(loginView);
} else {
filterChain.doFilter(servletRequest, servletResponse);
}
servletContext.log("Exiting the filter");
}
public void destroy() {
//Nothing to do.
}
}
答案 0 :(得分:7)
FacesContext
由FacesServlet
创建。当你进入过滤器时,它尚未被调用。过滤器在servlet之前运行。因此,您永远无法联系过滤器中的FacesContext
。另外,面部消息是请求作用域,因此重定向会使它们无论如何都会消失。
让login.xhtml
在<f:event type="preRenderView">
期间自行设置。最简单的方法是让过滤器暂时将其放在会话范围内。
session.setAttribute("message", message);
httpResponse.sendRedirect(loginView);
然后在login.xhtml
的预呈现视图侦听器方法中从会话范围中删除:
String message = (String) externalContext.getSessionMap().remove("message");
if (message != null) {
context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, message, null));
}
答案 1 :(得分:0)
我遇到了类似的问题,试图在EJB计时器中获取FacesContext。 BalusC已经在多个线程上指出,不可能这样做。或者,您可以使用'ServletContextListener',但ScheduledExecutorService并不像EJB计时器那样很好地定义调度。
在任何情况下,他提出的一个建议是实际向由托管bean支持的JSF页面发出Web请求,以利用我想用计时器设置的应用程序作用域bean上的方法。
我提到这一点,因为看起来你可以做类似的事情,你将一个参数传递给JSF页面,其中包含你想要的消息和用户的IP地址等等。该页面可以由请求范围的bean支持,该bean具有注入其中的应用程序范围的bean,该bean以IP作为键存储在映射中。然后,当用户被重定向到登录页面时,该页面可以在请求作用域bean上调用get错误消息方法,并将相同的应用程序作用域bean注入其中,从而获取该IP的错误消息或沿着这些行的某些内容。
无论如何,我确信BalusC的答案足够且比这更恰当,但是他的“只是向ejb计时器提出请求”的建议对于我在应用程序作用域上调度方法调用很有用,我想我可能会在这里提出它的可能用途。
@BalusC你对我指的帖子有什么看法吗?我找不到。