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.
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).
Inside the service I need the FlowScoped bean, but if I try to do
@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:
@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)
Thanks!
Instead using JSF FlowScoped
it is possible to obtain something very similar using ConversationScoped
.
From the book "JBoss Weld CDI for Java Platform" by Ken Finnigan:
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.
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:
<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.
If you want a complete example about creating wizard using the conversation scope take a look at this post .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.