JSF - Appropriate bean scope for keeping data between pages but only "browser tab related"

305 Views Asked by At

I am creating a web application using JSF 2.2.20 in which I am implementing a "kinda wizard" flow which lets the user filling input fields and go back and forth the view pages through navigation. I am using a single bean for all these views.

Let's say I have views A.xhtml, B.xhtml, C.xhtml and D.xhtml, all managed by the same bean MyBean.java

I want my application to be "browser tab scoped", which means that

  1. I do not want my bean's data be re-instantiated after every HTTP Request as it happens with @RequestScoped beans or after view changing as it happens with @ViewScoped, I want the data of my bean to be kept between view changes and redirections so the user can go back and forth between pages without losing the data he has already given.
  2. I do not want to use the @SessionScoped scope since each time the user opens a new tab I want the bean to be re-instantiated starting from page "A.xhtml.

Is there any built-in way to achieve the scenario described above using the current JSF version? In case there is not any, could you please propose any workarounds?

Thanks in advance!

1

There are 1 best solutions below

4
Jonathan S. Fisher On

I think @ViewScoped is what you are looking for, but it depends on your exact usage.

Couple of notes:

  • Use javax.faces.view.ViewScoped. Don't use the deprecated managed bean annotation as it works differently.
  • @ViewScoped works by storing the beans in the view. So each time you load the page you get a view and a viewId that corresponds to that view. So effectively each load of the page (could be read as 'each browser tab') gets its own bean.
  • @ViewScoped is a passivating scope. That means your beans, and their injected Dependencies, do need to be Serializable.
  • Use a recent, up-to-date version of your app server, or if you bring in MyFaces manually, use the latest release. I found a number of older versions implementations buggy 5+ years ago, but it seems to work flawlessly now.

If there is a Page Navigation occurring, you probably want to use FlowScoped. This is a multi-page bean that stays alive until you end the 'flow'.

If neither of these two work, you can always implement your own scope which is surprisingly easy with CDI.