简体   繁体   English

将FlowScoped bean注入Jersey REST Web服务

[英]Inject a FlowScoped bean into a Jersey REST Web Service

I'm developing an application that use a JSF flow to manage a wizard-like activity that can be started by a logged in user. 我正在开发一个使用JSF流来管理可由向导登录的用户启动的类似向导的活动的应用程序。

One page of the flow needs custom JavaScript code written in AngularJS, so I created a small Jersey REST service to exchange data between AngularJS and the bean (obviously the service should be called only when a user is using that flow page). 该流程的一页需要用AngularJS编写的自定义JavaScript代码,因此我创建了一个小型Jersey REST服务以在AngularJS和Bean之间交换数据(显然,仅当用户使用该流程页时,才应调用该服务)。

Inside the service I need the FlowScoped bean, but if I try to do 在服务内部,我需要FlowScoped bean,但是如果尝试这样做

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

    @Inject
    MyFlowScopedBean myFlowScopedBean;

    // ...
}

The following exception is thrown: 引发以下异常:

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

So, I'm using a session scoped bean associated to the user to retrieve the bean using the following workaround: 因此,我正在使用与用户关联的会话范围的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();
    }

    // ...
}

Is there a better way to do this? 有一个更好的方法吗? And, more important, should I do this or am I violating some best practices/conventions? 而且,更重要的是,我应该这样做还是违反一些最佳做法/惯例?

(I'm deploying on Glassfish 4.1) (我正在Glassfish 4.1上进行部署)

Thanks! 谢谢!

Instead using JSF FlowScoped it is possible to obtain something very similar using ConversationScoped . 代替使用JSF FlowScoped ,可以使用ConversationScoped获得非常相似的内容。

From the book "JBoss Weld CDI for Java Platform" by Ken Finnigan: 从Ken Finnigan撰写的“ Java平台的JBoss Weld CDI”一书中:

The conversation context implementation within Weld was developed to be used specifically with JSF. Weld中的对话上下文实现被开发用于JSF。 [...] In CDI 1.1, the tight coupling with JSF will be removed, enabling the conversation context to be used with other web frameworks. 在CDI 1.1中,将消除与JSF的紧密耦合,从而使对话上下文可以与其他Web框架一起使用。

Here a minimal working example (inspired by 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() {
        // ...
    }
}

In .xhtml: 在.xhtml中:

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

Warning : pay attention using @FormParam : grizzly seems to have problems with it. 警告 :使用@FormParam注意:grizzly 似乎有问题

If you want a complete example about creating wizard using the conversation scope take a look at this post . 如果您想要有关使用对话范围创建向导的完整示例,请查看此文章

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM