【问题标题】:Inject a FlowScoped bean into a Jersey REST Web Service将 FlowScoped bean 注入 Jersey REST Web 服务
【发布时间】:2016-02-01 14:23:21
【问题描述】:

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

流程的一个页面需要使用 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();
    }

    // ...
}

有没有更好的方法来做到这一点?而且,更重要的是,我应该这样做还是违反了一些最佳实践/惯例?

(我在 Glassfish 4.1 上进行部署)

谢谢!

【问题讨论】:

  • JAX-RS 和 JSF 是完全独立的框架,有各自不同的用途,无论如何不能在服务器端相互通信。设计失败,可能需要重新考虑。
  • 我看到了混合 CDI 和 Rest 服务的各种示例(在 JBoss Weld 的书中也有专门介绍 AngularJS 的最后一章)。我只需要我的流程的一页使用 JavaScript+REST 而不是 JSF 方法。

标签: java rest jsf jersey cdi


【解决方案1】:

如果使用 JSF FlowScoped,则可以使用 ConversationScoped 获得非常相似的东西。

摘自 Ken Finnigan 的“JBoss Weld CDI for Java Platform”一书:

Weld 中的对话上下文实现是专门为与 JSF 一起使用而开发的。 [...] 在 CDI 1.1 中,与 JSF 的紧密耦合将被移除,从而使会话上下文能够与其他 Web 框架一起使用。

这是一个最小的工作示例(灵感来自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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-16
    • 2012-09-10
    • 2015-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-05
    • 1970-01-01
    相关资源
    最近更新 更多