1

We have a JSF2 based web application which models a purchase process, where the user enters and selects different information in a wizard-like manor, can navigate forward and backward and at some point finishes the process.

So nothing special, a typical conversation between the application and the user. For that I tried both the regular and the MyFaces conversation scope, but although I know how to begin and end a conversation. I still don't manage to ensure an active conversation, so in other words how do I avoid a user entering the process in the middle by typing the pages URL and instead of that redirecting him to step 1?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Alexander Rühl
  • 6,769
  • 9
  • 53
  • 96
  • Well, instead of voting me down, it would be more helpful to tell me why my question is bad or even better point me to some information or example... – Alexander Rühl Jan 10 '13 at 12:08
  • I am not the downvoter but this is very generic question and you can find out many different solutions. Using mvc workflow, or storing steps in a backed bean, if first step bean called but step parameter is 2 then warn user, storing info in cookie, using encoded url and decode for each request etc... – HRgiger Jan 10 '13 at 12:46
  • I did several projects with Seam 2 and there I had the possibility to use `` and `` in a page descriptor to ensure an active conversation and redirect if not present. Now with JSF 2 and CDI I need something equivalent and hoped to be able to do this with a `@ConversationScoped`bean. If this is not possible, I would like to see some best practice how to solve this common problem. – Alexander Rühl Jan 10 '13 at 13:02

1 Answers1

0

You can't avoid that. The enduser has full freedom over manipulating the request URL. Your best bet would be to stick to a single view/URL wherein the wizard steps are conditionally (ajax-)rendered based on the state of the view. This way the enduser can only navigate by the buttons provided in the UI and not by manipulating the URL.

E.g.

<h:panelGroup rendered="#{wizard.step == 1}">
   <ui:include src="/WEB-INF/wizard/step1.xhtml" />
</h:panelGroup>
<h:panelGroup rendered="#{wizard.step == 2}">
   <ui:include src="/WEB-INF/wizard/step2.xhtml" />
</h:panelGroup>
<h:panelGroup rendered="#{wizard.step == 3}">
   <ui:include src="/WEB-INF/wizard/step3.xhtml" />
</h:panelGroup>

Also, this way you can get away with a single @ViewScoped bean instead of a @ConversationScoped one (with MyFaces CODI you would be able to use JSF @ViewScoped on a CDI @Named, for the case that is important).

Further, PrimeFaces has a <p:wizard> component which does almost exactly like that. You may find it useful in order to save yourself from some painful boilerplate code as to validation and such.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks for the hint. Both cases are a bit of a hassle for me, since there is already lots of handler and view code which has to be changed then (which is no excuse, I know, but still I like to avoid it) and additionally I experienced problems while using RichFaces and a second framework like IceFaces at the same time, which maybe the same with PrimeFaces then. I'm going to accept this as an answer - still I would like to know if the Seam guys have done something similar now to the above mentioned feature they had in Seam 2? – Alexander Rühl Jan 11 '13 at 10:55
  • You're welcome. As to Seam, sorry I don't have hands on experience with it. – BalusC Jan 11 '13 at 11:21