Craig, Adam B., I don't think Converters are a good path to go down here. Converters are globally registered, not contextually, so they don't reflect the local meaning of what a "personId" might mean, which is certainly not going to be a fixed mapping across an entire application. They're also generally supposed to used alongside of a UIComponent - which is explicitly *not* what's happening here. Finally, Converters exist for user-friendly, Localized presentation of data, whereas URLs parameters should always be non-Localized. You can hack around these things, but cumulatively, they should represent a clear message that Converters aren't the right way to go!
I agree with Adam B. that user-friendly errors are sort of besides the point here - another thing pointing away from Converters - since errors in URLs point to either system malfunctions or malicious misuse (or, sometimes, stale URLs), and all should be directed to (user-friendly) error pages - a 404 Page Not Found as a pretty good starting point. I think you want a system that is much more driven by, for example, annotations, and is ELResolver based - since an ELResolver will very specifically be operating on a specific property of a given bean in a very specific context. There is a common tendency for developers using JSF to see any "String in, Object out" case as being Converter-based; I'd recommend against making that assumption. ;) -- Adam On 4/14/06, Craig McClanahan <[EMAIL PROTECTED]> wrote: > On 4/14/06, Adam Brod <[EMAIL PROTECTED]> wrote: > > > > > > > But in your example, personId is a primitive. What I really want is to > pass my own model objects from the List to the Detail page (without > post-backs). Would your example work if personId were a PersonIdentifier > object? > > > No. As I mentioned earlier, the set of conversions supported is the same as > those for <jsp:setProperty>, which basically means you get the primitives > for free, but need to convert other things yourself. > > > > > What about other custom properties such as Enums, EmailAddresses, etc? > If so, then how? Does it invoke converters at ManagedBean creation time? > > > JSF 1.1 (and 1.2) don't currently do this for you, but you certainly could > do it yourself if you've registered your own JSF converters for these types. > You'd code the properties like personId as strings, and then in the logic > that deals with them, do something like this: > > FacesContext context = FacesContext.getCurrentInstance(); > Converter converter = > context.getApplication().getConverter("PersonIdentifierConverter"); > PersonIdentifier pi = (PersonIdentifier) converter.getAsObject(context, > null, getPersonId()); > > > > > Adam Brod > > Product Development Team > > Craig > > > > > > > > > > "Craig McClanahan" <[EMAIL PROTECTED]> > > Sent by: [EMAIL PROTECTED] > > > > > > 04/14/2006 06:31 PM > > > > > > Please respond to > > "MyFaces Discussion" <users@myfaces.apache.org> > > > > > > To "MyFaces Discussion" <users@myfaces.apache.org> > > > > cc > > > > > > Subject Re: JSF can handle GET requests *just as easily* as other > frameworks > > > > > > > > > > > > > > > > > > > > > > On 4/14/06, Adam Brod <[EMAIL PROTECTED] > wrote: > > > > Craig- > > > > Thanks for your response. I understand that the existing Shale remoting > code wouldn't work, but as you wrote - the same principle could be applied. > > > > > > "However, dealing with conversion errors on unedited request > parameters (it'll likely throw an exception) is probably not as user > friendly as it really ought to be. " > > > > Back to parameter mapping: since we are talking about request URLs, we > don't generally need to be concerned about user-friendly errors. A > malformed URL is a developer error in this case. In most cases, we'd > probably be "passing" the id from the person list to the person detail page. > (To be clear, I'm talking about using action-style urls just for > navigation, not for form submissions where we expect conversion errors. I > find that navigating from a list page to a detail page is too heavy-weight > using post-backs with potentially large datasets.) > > > > As an added benefit, you can get bookmarkable URLs out of the deal too. > > > > If the framework didn't do this and I were to use longs and Strings in my > managed bean properties, then I'd have to write code that creates the model > objects. In the exceptional case that the primitive managed properties > couldn't be converted, I would probably just throw an exception. Exceptions > are generally okay for developer errors that can be fixed at development > time. I'd rather the framework do this basic conversion for me since it > works great 90+% of the time. If I have a special case that needs special > error handling, I'll hand-code those few cases (or use post-backs). > > > > Does that make sense? > > > > Yep, that makes sense. Indeed, JSF today does what you want already. > Here's a pattern I've used that makes life pretty easy: > > > > <managed-bean> > > <managed-bean-name>backing</managed-bean-name> > > <managed-bean-class>com.foo.BackingBean</managed-bean-class> > > <managed-property> > > <property-name>personId</property-name> > > <value>#{param.personId}</value> > > </managed-property> > > </managed-bean> > > > > with a backing bean like this: > > > > public class BackingBean implements ViewController { > > > > private int personId; > > public int getPersonId() { return this.personId; } > > public void setPersonId(int personId) { this.personId = personId; } > > > > ... > > > > public void prerender() { > > // By the time you get here, personId has aready > > // been converted and injected, so use it to go look > > // up the relevant information > > } > > > > } > > > > No muss ... no fuss ... if you're willing to have the exception thrown on > a conversion error. > > > > > > Adam Brod > > Product Development Team > > > > Craig > > > > > > "Craig McClanahan" <[EMAIL PROTECTED] > > > Sent by: [EMAIL PROTECTED] > > > > 04/14/2006 05:42 PM > > > > > > > > > > Please respond to > > "MyFaces Discussion" <users@myfaces.apache.org > > > > > > > To "MyFaces Discussion" <users@myfaces.apache.org > > > > > cc > > > > > > Subject Re: JSF can handle GET requests *just as easily* as other > frameworks > > > > > > > > > > > > > > > > > > > > > > > > On 4/14/06, Adam Brod < [EMAIL PROTECTED]> wrote: > > > > If you wanted a GET to execute an action (and pass parameters), why not > adapt Shale's url convention > /[managedBeanName]/[actionMethod] (for example: > /documentController/documentID?id=1234)? > > > > This capability was specifically designed for being the back end of AJAX > style requests, but it works quite nicely for bookmarkable URLs too. > However ... > > > > That would enable GET requests to go through the NavigationHandler and > have even more of the JSF framework goodness. > > > > You don't get this out of the box with the current implementation in > Shale. That's because, from a JSF lifecycle point of view, Shale's phase > listener fires after Restore View -- and it will do this: > > > > * Determine that the URL matches one of the patterns it is configured > > to watch for (/dynamic/* by default) > > > > * Execute the corresponding method via a programmatic method > > binding call. As a side effect, this might trigger managed bean > > creation of the bean instance containing this method. > > > > * Expect that the method has created the entire response, so it > > calls FaceContext.responseComplete() and returns. > > > > As you can see, we never actually entered Invoke Application phase, we > never pay attention to anything that the invoked method returns (indeed, the > expected method signature is "public void methodname()"), and we never > invoke the navigation handler. > > > > That's not saying you couldn't configure a Processor that does that sort > of thing -- its just that the default one doesn't. > > > > For a use case like a bookmarkable URL, I tend to take a different > approach, because of what JSF's lifecycle will do for you anyway -- if > Restore View detects that there is no view state to restore, it jumps > immediately to Render Response phase. If you can interpose some processing > logic that happens right before rendering, and hav that logic pull out the > request parameters you need (or let JSF inject them via the managed > properties stuff), then it is very straightforward to process GET requests. > Shale even gives you a very easy place to put this kind of logic, if your > backing bean implements ViewController -- stick it in the prerender() > method. This approach certainly isn't harder than doing the same sort of > thing in Struts 1.x. > > > > Regarding conversion of request parameters to model data types, Section > 5.3.1.2 of the JSF 1.1 spec discusses using managed properties to inject > values into managed beans as they get created. It requires the same > implicit conversions that JSP provides for the <jsp:setProperty> tag, so > you're covered for things like Java primitives, but not for custom data > types. That means you could use a value expression like "#{ param.personId} > to pull out the personId request parameter, and assign it to a bean property > of type int or long. However, dealing with conversion errors on unedited > request parameters (it'll likely throw an exception) is probably not as user > friendly as it really ought to be. I would tend to use string properties > for that reason. > > > > Adam Brod > > Product Development Team > > > > > > Craig > > > > > > > >