Pass an object between @ViewScoped beans without using GET params
Asked Answered
P

1

17

I have a browse.xhtml where I browse a list of cars and I want to view the details of the car in details.xhtml when a "View more" button is pressed. Their backing beans are @ViewScoped and are called BrowseBean and DetailsBean, respectively.

Now, I wouldn't like the user/client to see the car ID in the URL, so I would like to avoid using GET params, as presented here and here.

Is there any way to achieve this? I'm using Mojarra 2.2.8 with PrimeFaces 5 and OmniFaces 1.8.1.

Pagination answered 5/9, 2014 at 21:46 Comment(0)
E
45

Depends on whether you're sending a redirect or merely navigating.

If you're sending a redirect, then put it in the flash scope:

Faces.setFlashAttribute("car", car);

This is available in the @PostConstruct of the next bean as:

Car car = Faces.getFlashAttribute("car");

Or, if you're merely navigating, then put it in the request scope:

Faces.setRequestAttribute("car", car);

This is available in the @PostConstruct of the next bean as:

Car car = Faces.getRequestAttribute("car");

See also:

Note that I assume that you're very well aware about the design choice of having two entirely separate views which cannot exist (be idempotent) without the other view, instead of having e.g. a single view with conditionally rendered content. And that you already know how exactly the view should behave when it's actually being requested idempotently (i.e. via a bookmark, shared link, by a searchbot, etc). If not, then I strongly recommend to carefully read the answer on this question: How to navigate in JSF? How to make URL reflect current page (and not previous one).


Update: in case you're not using OmniFaces, use respectively the following:

FacesContext.getCurrentInstance().getExternalContext().getFlash().put("car", car);
Car car = (Car) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("car");
FacesContext.getCurrentInstance().getExternalContext().getRequestMap().put("car", car);
Car car = (Car) FacesContext.getCurrentInstance().getExternalContext().getRequestMap().get("car");
Estimative answered 6/9, 2014 at 7:2 Comment(10)
Thanks for your reply, but I am getting a ClassNotFoundException on Faces.setFlashAttribute("car", car);, here is the trace. The omnifaces library scope, is set to compile, is that correct? (Tried setting it to runtime, and I got the same exception again)Pagination
OmniFaces is missing in runtime classpath. Apparently the Maven build failed somehow. OmniFaces must (exactly like PrimeFaces) end up in /WEB-INF/lib folder of the build. The default scope (compile) should work fine.Estimative
I've tried mvn compile and it has completed successfuly. This is the scope I have now. I even declared it explicitly at the pom.xml, but I am still getting the exception. Should I download the jar and add it to the WEB-INF/lib folder like with Primefaces, or post a new question to resolve this?Pagination
This is indeed basically an unrelated problem. But how exactly did you install PrimeFaces? Are you saying that you manually placed PrimeFaces JAR in /WEB-INF/lib? And thus effectively you're not using Maven to build?Estimative
The thing is that I haven't succeeded in installing Primefaces, as reported here, so I downloaded the primefaces-5.0.jar into the WEB-INF/lib folder. I probably have messed up my configuration, this is really the first time working with all those tools and using Java EE.Pagination
I don't do IDEA, but based on my Eclipse experience, the symptoms indicate that the IDE isn't being aware to use Maven during autobuilding of the project and stubbornly uses its own WAR build process. This isn't specifically related to PrimeFaces or OmniFaces. You'd have exactly the same problem with any other 3rd party library you declare in the pom.Estimative
Hmm, I'll see what I can do. All in all, thanks a lot for your support! Also, your solution (with Faces) worked perfect :)Pagination
Hi @BalusC. 1- If i want to pass the object to the third Facelet page backing bean, should again, put it into the request map of the ExternalContext? 2- If there are two choices, one passing the id of the object as a request parameter and then get the object using the<f:viewAction> from the database in the next Facelet page and two passing the abject as a request map key/value to the next Facelet page backing bean, which you choose and (if possible in the comment) Why?Clog
@Arash: that's already explained and linked in paragraph starting with "Note".Estimative
Thanks @BalusC. I've read them before. I will read them carefully again.Clog

© 2022 - 2024 — McMap. All rights reserved.