执行JSF导航时,不会调用映射在前向调度程序上的filter

我正在尝试使用Tomcat 7使用登录系统编写一个简单的JSF Web应用程序。

我有两个页面:index.xhtml和/restricted/welcome.xhtml。

“/ restricted / *”下面的页面只能由登录的用户访问。

直接浏览welcome.xhtml导致我的filter被执行,从index.xhtml转发到welcome.xhtml绕过filter。 我无法想象为什么不执行filter。

RestrictedAreaFilter.java:

@WebFilter(value = { "/restricted/*" }, dispatcherTypes = { DispatcherType.FORWARD, DispatcherType.REQUEST, DispatcherType.ASYNC, DispatcherType.ERROR, DispatcherType.INCLUDE }) public class RestrictedAreaFilter implements Filter { @Override public void destroy() { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpReq = (HttpServletRequest) request; User user = (User) httpReq.getSession().getAttribute("user"); if (user != null && user.isLoggedIn()) { chain.doFilter(request, response); } else { httpReq.getRequestDispatcher("/access_denied.xhtml").forward(request, response); } } @Override public void init(FilterConfig arg0) throws ServletException { } } 
    Login                 
 @ManagedBean(name = "login") @RequestScoped public class LoginBean { @ManagedProperty(value = "#{user}") private User user; private String username; private String password; public void setUser(User user) { this.user = user; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String proceed() { user.setLoggedIn(true); return "restricted/welcome.xhtml"; } } 

仅当在webapp的代码中的某处调用RequestDispatcher#forward()时,才会触发FORWARD调度程序。 标准的JSF导航处理程序不会这样做。 它只调用ViewHandler#createView()并将其设置为FacesContext#setViewRoot()当前视图。

发送重定向:

 public String proceed() { user.setLoggedIn(true); return "restricted/welcome.xhtml?faces-redirect=true"; } 

这也是推荐的做法。 现在它是一个可collections的页面(URL更改现在反映在浏览器的地址栏中)和刷新/ F5页面不会导致POST被不必要地重新执行,按下后退按钮不会导致意外。

如果您确实坚持使用JSF调用FORWARD调度程序,则可以始终使用ExternalContext#dispatch()方法,但这不是推荐的方法。

 public void proceed() throws IOException { user.setLoggedIn(true); FacesContext.getCurrentInstance().getExternalContext().dispatch("restricted/welcome.xhtml") }