aspose file tools*
The moose likes JSF and the fly likes Translating GET parameters to POST parameters. There's got to be a better way. Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » JSF
Bookmark "Translating GET parameters to POST parameters. There Watch "Translating GET parameters to POST parameters. There New topic
Author

Translating GET parameters to POST parameters. There's got to be a better way.

Rob Micah
Ranch Hand

Joined: Aug 30, 2011
Posts: 94
I have a @RequestScoped @ManagedBean that accepts a GET request with a single parameter ("ptk"). I want that parameter passed on to the next @ManagedBean which is @SessionScoped in the subsequent request. I have tried this 2 ways using jsf tags with 1 failing and 1 working...maybe.

Attempt #1: use the parameter as an attribute

In the above method the attribute always evaluates to null and is dropped.


Attempt #2: Insert an unused property in the facelet and extract the parameter in a @PostConstruct


This actually seems to work but is there a better way to do this than putting in a dummy property?
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16305
    
  21

Any time you start including javax,faces classes other than model classes, there's a good chance you're not doing it right.

As a general rule, JSF shouldn't be rooting around in J2EE data structures to pull in data. JSF is based on Inversion of Control, which is "push" based. JSF2, in fact, even added some extra functionality in order to further minimize the need for this kind of stuff.

The cleaner approach would be to inject your target backing bean as a managed property into the request-handling bean, then have the requesting bean directly inject the parameter value into the target bean. No need for any javax package code at all. No need to pass data out to the client (where it could be hacked).


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

Joined: Aug 30, 2011
Posts: 94
I just discovered the @ManagedProperty annotation. Looks like a good idea. Thanks. But when you say not to mess with javax.faces.* classes what specifically are you talking about? Wouldn't I still get the request from the HttpServletRequest object?
Rob Micah
Ranch Hand

Joined: Aug 30, 2011
Posts: 94
Also, 1 more question. When I refer to the @SessionScoped bean in my facelet should I refer to it as a child of the @RequestScoped bean or just by itself. In other words:

this

or this

Since it is scoped at the session it seems like it shouldn't matter but I wasn't sure about whether this would be some kind of race condition.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16305
    
  21

JSF was designed to allow you to use POJOs wherever possible. A POJO, by definition, doesn't subclass some platform-specific class or demand a platform-specific interface. Nor, in general, should it reference platform-specific functions.

In actual practice, there are 2 exceptions to this in JSF. Since JSF is designed as a MVC platform, but it's not possible to keep all the context that the JSF controllers need in POJO objects, you'll commonly need to include the DataModel and SelectItem classes from the javax.faces model packages.

Anything from any OTHER package should be carefully considered, though. I do have occasional need to dip into JSF internal objects. For example, to add info or error messages to the JSF view message collection. And, for that matter, there are cases where I have to go through there in order to get raw HTTP objects, such as unmanaged session beans, the login userId, and so forth. I let PrettyFaces handle my GET parameters. So I generally include an isolation class with the original name of "JSFUtils" that I dump all of those functions into - it's rarely more than about a dozen methods for a typical app. Keeps the JSF- and HTTP- specific stuff out of the application proper, which, in turn makes it a lot easier to run unit tests on the POJOs.

While you CAN refer to JSF backing beans from their scopes in Views, you normally wouldn't. In fact, it MIGHT even interfere with JSF's normal mechanisms, since JSF maintains the beans defined in faces-config (or from annotations) in a map of its own that already knows what the scope of an object is, and if you explicitly specify scope on the View, you might actually cause JSF to treat the object as an unmanaged bean, thereby losing and the rights and privileges of JSF's automated bean management.
Rob Micah
Ranch Hand

Joined: Aug 30, 2011
Posts: 94
The reason I asked is it doesn't seem to be clear whether accessing a SessionScoped bean via a ManagedProperty and also through its default value expression actually refer to the same object or create 2 separate instances.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16305
    
  21

JSF Session Scope is the exact same thing as J2EE session scope. The only difference is that in a Managed Bean, JSF will construct the bean and inject the Managed Properties on demand. Whereas, in vanilla J2EE you have to do the construction and initialization manually. Once instantiated, the bean will be pushed into the HttpSession object using that object's setAttribute() method. In the case of JSF, JSF will do that, otherwise, that, too is manual code.

Same thing applies to Application Scope and Request Scope. Page scope doesn't work in JSF. The new View and Flash scopes for JSF are just specialized forms of Session objects that have their own automated removal methods built into JSF.
Rob Micah
Ranch Hand

Joined: Aug 30, 2011
Posts: 94
This seems kindof odd to me because my RequestScoped bean has no other purpose than to initialize a property of the SessionScoped bean. And without putting some reference to the RequestScoped bean in the facelet it will never get constructed. So it looks like my options are to either add a dummy property on the RequestScoped bean or qualify the SessionScoped bean in the facelet by prefixing the RequestScoped bean name.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16305
    
  21

Well, I'm not sure I understand exactly what you're looking to do there, but Request Scope objects are pretty useless in JSF because they don't work well with postback operations, and that raises hob in particular with dataTable models. View Scope helps make that work better, though.

One thing I HAVE used request scope objects for, however, is things like search forms. For that particular case, the search form fields are all properties on the Request bean, the Session bean is injected into the Request bean as a managed property, the request bean is then used to do the search and program the injected session bean with the results of the search.

Now, of course, if your goal is something more like a bookmarkable page access via HTTP GET request, a session-scope backing bean can do all that stuff about getting the FacesContext to get the HttpServeltRequest to get the request parameter(s) directly (although like I said, I usually have a utility class that does that). Just watch out for the postback effects, etc..

A much cleaner approach, however, is to use the JSF2 parameter enhancements and/or PrettyFaces. They will inject the GET parameters straight into the bean without having to write any code that uses javax.faces objects or even javax.servlet objects.
Rob Micah
Ranch Hand

Joined: Aug 30, 2011
Posts: 94
I have a single page/view that retrieves a request parameter of the initial request which indicates a resource on the server to load and present a form to the user. The form can be posted back or the client can make a request with a different value of the request parameter in which case I want to locate a new resource.

So what I have done is create a RequestScoped bean with a SessionScoped bean as its ManagedProperty. The request bean checks the request parameters from the client and indicates to the session bean whether or not a resource needs to be loaded. But since the request bean really has no properties it doesn't need to be accessed in the facelet and therefore doesn't get initialized. That's how I came up with my 2 options above.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Translating GET parameters to POST parameters. There's got to be a better way.