将 FlowScoped bean 注入 Jersey REST Web 服务

Inject a FlowScoped bean into a Jersey REST Web Service

我正在开发一个应用程序,该应用程序使用 JSF 流程来管理类似向导的 activity,可以由登录用户启动。

流程的一页需要用 AngularJS 编写的自定义 JavaScript 代码,所以我创建了一个小的 Jersey REST 服务来在 AngularJS 和 bean 之间交换数据(显然是服务应仅在用户使用该流程页面时调用。

在服务内部我需要 FlowScoped bean,但如果我尝试这样做

@Path("rest")
@RequestScoped
public class MyResource {

    @Inject
    MyFlowScopedBean myFlowScopedBean;

    // ...
}

抛出以下异常:

exception java.lang.NullPointerException at com.sun.faces.flow.FlowCDIContext.getCurrentFlow

因此,我使用与用户关联的会话作用域 bean 来使用以下变通方法检索 bean:

@Named
@FlowScoped("myFlow")
public class MyFlowScopedBean {

    @Inject
    UserDataBean userDataBean;

    @PostConstruct
    public void init() {
        userDataBean.setMyFlowScopedBean(this);
    }

    // ...
}

@Named
@SessionScoped
public class UserDataBean {

    private MyFlowScopedBean myFlowScopedBean;

    public getMyFlowScopedBean() {
        return myFlowScopedBean;
    }
    public setMyFlowScopedBean(MyFlowScopedBean myFlowScopedBean) {
        this.myFlowScopedBean = myFlowScopedBean;
    }

    // ...
}

@Path("rest")
@RequestScoped
public class MyResource {

    @Inject
    UserDataBean userDataBean;

    private MyFlowScopedBean getMyFlowScopedBean() {
        return userDataBean.getMyFlowScopedBean();
    }

    // ...
}

有更好的方法吗?而且,更重要的是,我应该这样做还是违反了一些最佳 practices/conventions?

(我正在 Glassfish 4.1 上部署)

谢谢!

而不是使用 JSF FlowScoped 可以使用 ConversationScoped.

获得非常相似的东西

来自 Ken Finnigan 的书 "JBoss Weld CDI for Java Platform":

The conversation context implementation within Weld was developed to be used specifically with JSF. [...] In CDI 1.1, the tight coupling with JSF will be removed, enabling the conversation context to be used with other web frameworks.

这里是一个最小的工作示例(灵感来自 this blog post):

@Named("foo")
@ConversationScoped
public class FooBean implements Serializable {

    @Inject
    Conversation conversation;

    public String getConversationId() {
        return conversation.getId();
    }

    @PostConstruct
    public void init() {
        conversation.begin();
    }

    // ...
}

@Path("foo")
@ConversationScoped
public class FooResource implements Serializable {

    @Inject
    FooBean fooBean;

    @GET
    @Path("myMethod")
    public String myMethod() {
        // ...
    }
}

在 .xhtml 中:

<script>
    var CID = '#{foo.conversationId}'; // <-- EL
    $.get('/myApp/foo/myMethod?cid=' + CID);
</script>

警告: 注意使用@FormParam: grizzly seems to have problems 用它。

如果您想要有关使用对话范围创建向导的完整示例,请查看 this post