有没有简单的方法来预处理和redirectGET请求?

我正在寻找一个最佳实践的答案。 我想对GET请求进行一些预处理。 因此,例如,如果用户不被允许看到该页面,则将其redirect到另一个页面。 但是我不想使用普通的servletfilter,因为我想在faces-config.xmlexpression这种行为。 这是可能的,那是怎么回事,怎么办?

我可以定义一些Filter bean,它也返回一个string告诉faces-config.xml接下来要去哪里?

我GOOGLE了这一点,但只打在正常的filter。 如果我使用filter,可以@WebFilter是一个@ManagedBean在同一时间吗? 还是那种不好的风格?

如果您在JSF之上正在生长HTTP请求authentication,那么servletfilter确实是最好的方法。 JSF只是一个MVC框架,并没有指定JSF API来过滤传入的HTTP请求来检查用户身份validation。 在普通的GET请求中,JSF托pipebean通常只在HTTP响应即将被创build和发送时被构build,或者可能已经被提交。 这不能从托pipebean内部控制。 如果响应已经被提交,你将不能再改变(redirect)它。 authentication和改变请求/响应确实需要在即将发送响应之前完成。

如果您没有自我authentication,那么您可以使用Java EE提供的容器pipe理的身份validation,这将由web.xml <security-constraint>条目声明。 请注意,这也是从JSF中分离出来的,但它至less可以帮助您避免在servletfilter和托pipebean之间生长。

一般的做法是将受限制的页面组织在/app/*/private/*/secured/*等特定URL模式后面,并利用JSF将会话作用域bean存储为HttpSession属性的优势。 想象一下,你有一个JSF会话作用域pipe理bean UserManager ,它持有login的用户,那么你可以检查它,如下所示:

 @WebFilter(urlPatterns={"/app/*"}) public class AuthenticationFilter implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; HttpSession session = request.getSession(false); UserManager userManager = (session != null) ? (UserManager) session.getAttribute("userManager") : null; if (userManager == null || !userManager.isLoggedIn()) { response.sendRedirect(request.getContextPath() + "/login.xhtml"); // No logged-in user found, so redirect to login page. } else { chain.doFilter(req, res); // Logged-in user found, so just continue request. } } // ... } 

如果您使用的是JSF 2.2+,还有另一种方式可以在发送之前控制响应。 你可以使用<f:viewAction> 。 把你的看法放在以下的地方:

 <f:metadata> <f:viewAction action="#{authenticator.check}" /> </f:metadata> 

 @Named @RequestScoped // Scope doesn't matter actually. The listener will always be called on every request. public class Authenticator { public String check() { if (authenticated) { return null; } else { return "login?faces-redirect=true"; } } // ... } 

在响应被呈现之前,这保证被解雇。 否则,当你在例如@PostConstruct完成这个工作时,你可能冒着java.lang.IllegalStateException: response already committed风险java.lang.IllegalStateException: response already committed已经部分被渲染(提交)时,第一次创buildbean时java.lang.IllegalStateException: response already committed的响应。

在处理HTTP身份validation时,我只会认为这不是一个“最佳”的做法。 这使得JSF紧密耦合在一起。 你应该继续使用一个servletfilter。 但是为了其他目的,这可能是好的。

也可以看看:

  • 何时使用f:viewAction / preRenderView与PostConstruct?
  • 什么可以使用<f:元数据>,<f:viewParam>和<f:viewAction>?
  • 使用PhaseListener而不是Servlet Filter进行授权的限制