是否有简单的方法来预处理和重定向GET请求?



我正在寻找最佳实践答案。我想对GET请求做一些预处理。因此,例如,如果用户不允许看到的页面,重定向到另一个页面。但是我不想使用普通的servlet过滤器,因为我想在faces-config.xml中表达这种行为。这是可能的吗,怎么叫,怎么做?

我可以定义一些过滤器bean,也返回一个字符串告诉faces-config.xml下一步去哪里?

我在谷歌上搜索了这个,但只点击了正常的过滤器。如果我用过滤器,一个@WebFilter可以同时是一个@ManagedBean吗?或者这是糟糕的风格?

如果您在JSF之上自行开发HTTP请求身份验证,那么servlet过滤器确实是最好的方法。JSF"只是";没有指定MVC框架和JSF API中的任何内容来过滤传入的HTTP请求以检查用户身份验证。对于普通的GET请求,JSF托管bean通常只在即将创建和发送HTTP响应或可能已经提交时构造。这在受管bean内部是无法控制的。如果响应已经提交,您将无法再更改(重定向)它。身份验证和更改请求/响应确实需要在响应即将发送之前完成。

如果您不是自生长身份验证,那么您可以使用Java EE提供的容器管理身份验证,这是由web.xml中的<security-constraint>条目声明的。请注意,这也与JSF解耦了,但它至少使您不必自行开发servlet过滤器和托管bean。

一般的方法是将受限制的页面分组在特定的URL模式后面,如/app/*/private/*/secured/*等,并利用JSF将会话作用域bean存储为HttpSession属性的事实。假设您有一个JSF会话作用域的托管bean UserManager,它包含登录的用户,那么您可以按如下方式检查它:

@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中执行工作时,当响应已经部分呈现(并提交)时,bean第一次创建时,您可能会冒java.lang.IllegalStateException: response already committed的风险。

我只是不认为它是"最好的"。在处理HTTP身份验证时进行练习。这使得它与JSF的耦合过于紧密。您应该继续使用servlet过滤器。但对于其他用途,它可能是好的。

参见:

  • 何时使用f:viewAction/preenderview与PostConstruct?
  • 什么可以和& lt; f: viewAction>被用于?
  • 使用PhaseListener而不是Servlet Filter进行授权的限制

最新更新