@WebFilter 和 FacesContext.getCurrentInstance() -> Nullpointer

Posted

技术标签:

【中文标题】@WebFilter 和 FacesContext.getCurrentInstance() -> Nullpointer【英文标题】:@WebFilter and FacesContext.getCurrentInstance() -> Nullpointer 【发布时间】:2013-08-18 16:04:47 【问题描述】:

在我的应用程序中,我有一个 WebFilter。这个 Webfilter 应该检查一个 cookie。但是使用 FacesContext.getCurrentInstance() 会产生 Nullpointer 异常。我该如何解决这个问题?

网络过滤器:

@Inject
private CookieManager cm;   

[...]

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException 
    if(cm.isDoCheck())
        cm.doCheck();
    
    chain.doFilter(request, response);

[...]

执行 FacesContext.getCurrentInstance() 的 CookieManager:

[...]
private void doCheck()
    FacesContext context = FacesContext.getCurrentInstance();
    Map<String, Object> cookies = context.getExternalContext().getRequestCookieMap();

    Cookie cookie = (Cookie) cookies.get("frontend");
    if(cookie != null)
        setSessionHash(cookie.getValue());
    

[...]

context.getExternalContext().getRequestCookieMap(); 给出了

StandardWrapperValve[Faces Servlet]: Servlet.service() for servlet Faces Servlet threw exception
java.lang.NullPointerException

【问题讨论】:

【参考方案1】:

FacesContextFacesServlet 创建。 任何 servlet 之前调用任何 servlet 过滤器。因此,FacesContext 的定义在任何 servlet 过滤器中都不可用。

关于获取请求cookies的具体功能需求,你似乎也完全忽略了FacesContext是facade的一个ServletRequestServletResponseExternalContext 的方法全部委托给ServletRequest/ServletResponse 方法(这在其javadoc 中有明确提及,例如getRequestCookieMap())。您需要的 cookie 方法可以通过 doFilter() 方法的 ServletRequest 参数轻松获得。

HttpServletRequest hsr = (HttpServletRequest) request;
Cookie[] cookies = hsr.getCookies();
// Loop over cookies to find the one matching the name.

注意应该有一个hack/workaround 可用于根据ServletRequestServletResponse 变量在过滤器中自己创建FacesContext,但是如果这些信息很容易获得,那么这完全没有意义变量本身。

我建议暂停一下 JSF 并学习基本的 Servlet API。这基本上就是 JSF 在幕后使用的(你看,它的 FacesServlet 是“只是”一个 servlet)。阅读ExternalContext javadoc 中的方法描述还应该提示您在基本 Servlet API 中所有这些方法的确切位置。

【讨论】:

谢谢@BalusC。我明白。我将学习这些基础知识。根本上,在您回答后向我提出的问题是:什么是做我想做的正确方法?我还必须从我的应用程序的其他方法中调用此 doCheck() 方法,而不仅仅是从过滤器中。所以使用doFilter()方法的ServletRequest参数的方法不适合我。 过滤器是检查各种请求中的 cookie 的理想场所。过滤器允许您通过简单地调用 dispatcher.forward() 或 response.sendRedirect() 而不是 chain.doFilter() 来更改请求目的地。另见***.com/tags/servlet-filters/info

以上是关于@WebFilter 和 FacesContext.getCurrentInstance() -> Nullpointer的主要内容,如果未能解决你的问题,请参考以下文章

如何在过滤器中检索 FacesContext

FacesContext#getCurrentInstance() 在 Filter#doFilter() 中返回 null

JSF - JUnit FacesContext模拟测试

无法从 Servlet 过滤器中的 FacesContext 检索 Session

FacesContext.getCurrentInstance() 在 FacesServlet(?) 处理的请求中返回 null

WebFilter 和 RewriteConfiguration 冲突