2

我刚刚将 SessionScoped bean 更新为 OmniFaces (1.6.1) ViewScoped。一切似乎都正常工作,除了当我的支持 bean 被注入我用于处理 ajax 请求的 Servlet 时,我得到以下异常:

org.jboss.weld.context.ContextNotActiveException: WELD-001303 No active contexts for scope type org.omnifaces.cdi.ViewScoped

需要考虑的一些事项:

1) 我必须将支持 bean 注入 servlet 的原因是因为我使用的是 jQuery 的 DataTables 插件,该插件(用于服务器端处理表)需要 ajax 请求来检索表数据。所以基本上我不能使用 Primefaces<p:remoteCommand..>或类似的东西。

2)据我所知,没有任何额外的 GET 请求会破坏和重新创建支持 bean。

还有其他可能导致此异常的原因吗?另外,如果这不能完成,是否有另一种方法来实现我正在做的事情?

4

1 回答 1

3

注释将 bean 与特定的 JSF 视图联系起来,而@ViewScoped后者又依赖于FacesContext#getViewRoot()和 随后的UIViewRoot#getViewMap()。两者都不能在“plain vanilla”servlet 中使用。在普通的 servlet 请求中没有 JSF 视图,更不用说 JSF 上下文了。因此,不幸的是,这种行为是“设计使然”。

你基本上有两个选择:

  1. 将所需的共享信息存储在会话范围中,该信息由作为 HTTP 请求参数传递的唯一键作为键,以便 JSF 托管 bean 和 servlet 都可以从会话范围中获取它。

    例如在 JSF 支持 bean 中:

    dataId = UUID.randomUUID().toString();
    externalContext.getSessionMap().put(dataId, data);
    

    在 JSF 视图中:

    <h:outputScript>var dataId = "#{bean.dataId}";</h:outputScript>
    

    在 JavaScript 中:

    function loadData() {
        $.get("servletURL", { dataId: dataId }, function(response) {
            // ...
        });
    }
    

    在小服务程序中:

    String dataId = request.getParameter("dataId");
    Data data = (Data) session.getAttribute(dataId);
    

  2. 使用真正的 JSF 支持 bean 而不是普通的 servlet。你绝对可以使用<p:remoteCommand>它。您可以使用RequestContext#addCallbackParam()in action(listener) 方法将 JSON 对象从 Java“传递”(“打印”在技术上更正确)到 JS,最后使用oncomplete属性来处理它。鉴于您使用的是 OmniFaces,<o:commandScript>Ajax#data()提供相同的功能。它Ajax#data()还有一个额外的优势,它会自动从 Java 转换为 JSON,这样您就不需要自己动手了。

    例如在 JSF 视图中:

    <o:commandScript name="loadData" action="#{bean.loadData}" oncomplete="processData()" />
    

    在 JSF 支持 bean 中:

    public void loadData() {
        Ajax.data(data);
    }
    

    在 JavaScript 中:

    function processData() {
        var data = OmniFaces.Ajax.data;
        // ...
    }
    
于 2013-10-02T14:26:33.777 回答