This week's book giveaway is in the OCPJP forum.
We're giving away four copies of OCA/OCP Java SE 7 Programmer I & II Study Guide and have Kathy Sierra & Bert Bates on-line!
See this thread for details.
The moose likes JSF and the fly likes Better to use rendered in xhtml or branching code in bean method? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of OCA/OCP Java SE 7 Programmer I & II Study Guide this week in the OCPJP forum!
JavaRanch » Java Forums » Java » JSF
Bookmark "Better to use rendered in xhtml or branching code in bean method?" Watch "Better to use rendered in xhtml or branching code in bean method?" New topic
Author

Better to use rendered in xhtml or branching code in bean method?

john lazeraski
Ranch Hand

Joined: Nov 14, 2011
Posts: 76
Hey all,

I'd like to learn the best (or more common) way to handle conditional navigation and thus what is displayed "next". In my case, the first time a user registers, I keep a flag of the last step they were on. For example, after they activate their account, the status may be set to 1. If they are at step 1, I want to show some text and a form for them to enter some data. If they completed that, when they log in (or upon completing it, the next step) is to show another form. It's wizard like, but they may also come back to any of these specific forms at a later time to add more to them, change them, etc.

My first thought was to have the initial page (/loggedin/index.xhtml) use the rendered="" attribute in a h:panelGroup or something, such that if they were step 1, one specific panel group (and children) would be rendered, the others would not due to the rendered="" conditionals being false. If they were on step 2, a different panel is rendered. Going from step 1 to step 2 could be a post back or a redirect to the same page but with the update state causing the next panel to show up.

The other option, the one that I think makes more sense, is in the login bean method, or at any step really, returning a navigation string configured in faces-config, that causes a redirect to a specific page, such that each of the panels in the above scenario would be their own pages.

The problem I am facing though, is in some cases, some of these panels in the first scenario my need to be on one page, later on during editing, but initially as part of a "setup" wizard I want them to be individual. Therefore, I am thinking what I really need is composite components that can be reused in different views... but then, should the setup "wizard" still use individual pages where each page uses the component, or would it make more sense to use a single page with panels that show/hide depending on a condition?

Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16158
    
  21

Well, to digress for a moment, there is a technical term for web applications that contain "loginbean", "login code" or similar components. That term is "hacked".

If I seem unkind about it, it's because I've seen too many user-designed "security systems" over the years, and finance or military, large or small, pretty much every stupid one of them had security holes you could drive a jumbo airliner through. Most of them could be short-circuited by non-technical people in under 5 minutes. I chewed someone out yesterday for creating one that could potentially permit wiping out the entire database from the login screen. Without even logging in.

Leave security to the security professionals. J2EE has a perfectly-good authentication and authorization already built into it, designed according to strict standards, already debugged and with well over a decade of use under fire.

Now back to the primary issue.

You seem to be describing "wizard-like" behavior where you want to establish a workflow as a sequential set of displays with the ability to traverse backwards and forwards. That is essentially a finite state machine architecture, so what may prove useful is to maintain a session-scope managed bean that holds the state and has action methods that support operations like "forward", "backward", "finish", and so forth. You could then inject that bean into view-scoped managed beans for the individual screens to allow them to interact with the state machine bean as needed.

As a general rule, I'd recommend using separate web pages for the separate steps in the workflow. You can pair them with a shared layout definition to provide them with a consistent appearance. Separate pages will be easier to maintain than one big show-em/hide-em page, usually. I would make exception in cases where only a small part of a page changes and I want to keep the disruption down, but when the bulk of the page changes, it's easier and cleaner to use discrete pages.


Customer surveys are for companies who didn't pay proper attention to begin with.
john lazeraski
Ranch Hand

Joined: Nov 14, 2011
Posts: 76
Hi Tim,

I think we went over security or maybe it was BalusC from the other forum..can't remember. I was originally going to use JEE security, but I ended up going to Shiro. I find it easier to work with, easy to set up access rights for user roles and define those roles, and from what I've read, it's every bit as good as JEE directly, with another added bonus that you can use it outside a JEE container. I have that in place now and it works great, tied to a couple tables (users and roles) and so far, I can't access any resources that I defined that require a specific user role to authenticate with. But I agree with you, after reading either you and/or BalusC's info on why the usual login forms with basic calls are so typical of apps and easy to circumvent, I recalled many a login form over the years that i've worked with that were exactly that. So I am glad I was able to find Shiro and implement what I believe to be a pretty secure login process.

Yes, I thought of what you are saying and as I said, I think it's a better design to use separate pages than trying to use the rendered property of panels to show/hide the panel on the same page. Makes it more difficult to maintain it as well.

Thus far, I have been using view scoped beans, and upon the "next" button being pressed, I typically update the database. So I don't know that I need a session bean in this case. When the page is rendered, I grab the data from the database if it's available. If not, it's an empty form (first time filling it out or they skipped it and are coming back to it if allowed to). I was trying to use request scope in these cases since I do store it in the db and pull it again from db to show it, but the post back stuff fails if I don't use view scoped, so I've been sticking to using view scoped.

So you pretty much confirmed what I thought.. which is using discrete pages as the user navigates the wizard like process.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16158
    
  21

I forgot you liked Shiro.

The main thing about using the container security is that unlike third-party add-ons, it is built into the API and web.xml of the J2EE standard itself. It also repels many types of exploits at the server level, and if the invasion attempt never reaches the application code at all, then there's zero chance that it can find and exploit security holes in the application code. Admittedly the standard security can be somewhat coarse-grained, but that's fine. You can refine it by combining it with co-operative frameworks such as Spring Security. I don't know if Shiro works that way, though.

Another reason I prefer the J2EE standard security is that it places the primary authentication and authorization completely outside of the webapp. That means that I can test secured apps without requiring access to the production security system. I can simplt plug in an XML security file and the MemoryRealm test without making changes to the application code.

I think your best bet is a session bean for the page-to-page navigation and control and View scope for the pages. Request scope is almost completely useless in JSF. Especially if you have tables in your forms.
john lazeraski
Ranch Hand

Joined: Nov 14, 2011
Posts: 76
Hi Tim,

When you say use a session bean, then inject viewscope beans.. does this mean each page of the wizard uses the session bean for things like action methods to call upon, and the session scoped bean has each of the view scoped beans injected in it? I am unclear how using a session bean and view bean at the same time would work or work together. Or why you would have both, as opposed to just one or the other?

Thanks.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16158
    
  21

Actually, it's the other way around. Each page in the sequence has a View-Scoped backing bean paired with it. The session-scope bean is injected (automatically by JSF) into each of those beans as they are constructed. The View Scoped beans use the session-scoped bean to manage the navigation process (the finite-state machine) and to hold any data that needs to be accessible from more than one View.

You can't inject View-Scoped beans into a Session-Scoped bean in any event, since you can never inject a short-lived bean into a longer-lived bean.
john lazeraski
Ranch Hand

Joined: Nov 14, 2011
Posts: 76
Thanks.. that makes sense. I have yet to have done anything like this so thank you for the info. Good to know.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Better to use rendered in xhtml or branching code in bean method?