On 4/4/06, Richard Wallace wrote:
Mike Kienenberger wrote:
Mike Kienenberger wrote:On 4/4/06, Richard Wallace wrote:
No matter what you do, you're still going to have to write java code
that consolidates messages to display them. It's just as easy to
consolidate FacesMessages as it is to consolidate some custom data
type that you'd conceivably generate in a custom required validator.
And the required validator controller component is slow due to the
fact that it has to walk the entire component tree a couple times in
order to fire the validation and then adjust the component validation
I guess you're right about the FacesMessages. The only thing I'm not
sure about is how to differentiate the messages I would want to
consolidate from messages that I want to display as is.
Note that your use cases for "consolidation" are probably on the 20% side of
the 80/20 rule :-).
Another thing that I find a little annoying is that you either have
messages tied to a component or global to the page. You can't have
messages tied to a form.
Don't feel limited to using the standard message and messages components.
If the messages themselves are tied to individual input components, writing
a version of the <h:messages> renderer that picks out only the messages for
components nested inside a particular form is pretty easy.
And, of course, one of the biggest pains is customizing messages on a
per component basis. What I want is to be able to set the message to be
displayed for a specific instance rather than for all types of that
component across the application.
I don't know, maybe the solution to my problem is to just have the
validation done in my backing bean. The thing is that that seems to be
the solution to a lot of my validation use cases. In fact, I don't
think I've run into a single real world use case where the standard JSF
That (validation in the backing bean) seems like the right answer for
*application* defined vaidations that cross multiple components, which
includes the use case you are describing. JSF's validation framework is
focused on single component sorts of validations.
Instead, you want to generate standard required validation messages,
then create a custom renderer for the messages component that
consolidates each of these messages into something else, probably by a
specific id pattern. I also think you'd be better off extending the
existing messages renderer than creating it yourself.
Sounds like a hack to get around a poor validation system.
In this case, it's not the validation system that's the problem. It's
the displaying of validation errors. The system logged them as
FacesMessages, so you simply need to change how they're displayed.
The messages component renderer is the place to change that.
But how do you differentiate the messages to be consolidated from those
that shouldn't be?
Here's a strategy for dealing with "all the errors related to components in
a particular form":
* Build a variant of the standard <h:messages> component that takes some
sort of reference to the containing form component.
* At rendering time for this component, start doing a recursive tree search
the form component's children.
* For each component that might have been a source of validation errors
test is "instanceof EditableValueHolder" but you might have special cases
call FacesContext.getMessages(String clientId) to grab any messages
to that client.
* Consolidate all the messages accumulated during this tree search in any
that you desire.
Is there any
way to completely replace the JSF validation process with something
flexible? I mean, honestly, this is a pretty simple use case that is
extremely difficult to implement.
Sure. JSF is completely pluggable, so you could create your own
lifecycle factory and create a lifecycle that skips or replaces the
process validation phase. However, coming up with something "more
flexible" is going to be a task. You're also going to probably break
components that expect a processValidation phase to occur. It'd be
interesting to hear what you have in mind. I've yet to see any
decent validation implementations. Before you get too far into it,
take a look at subforms (talked about more below) as they solve some
of the weaknesses of JSF validation.
I'm not sure of exactly what I'd do. At the moment I'm thinking that
the three things that I'd really like to see are more customizable
messages, required being a child element rather than a component
attribute, and for messages tied to forms in addition to global and
component messages. I was probably being a little extreme when I said
"completely replace". I was just on a bit of a rant cause I've spent to
much time banging my head against the wall trying to figure out the best
way of doing things with JSF validation.
As an example of the flexibility JSF does provide (but doesn't deal directly
with your particular issue), consider the fact that Shale lets you use
Commons Validator to implement client side (as well as server side)
validation on standard JSF components.
I have to wonder why the required
attribute is treated as a special case as well.
I think having the required attribute as a special case was an example
of an implementation detail influencing the spec. I'm sure the idea
is that if there's no value, then there's no point in validating it.
But unfortunately, it's an ugly special-case that you have to
constantly work around since it's not treated as a "real" validator
but is instead implemented separately as part of every component.
This was done primarily for usability reasons. The fundamental philosophy
was "there is no point in firing validators when there is no data to
validate" because a typical validator author would assume something would be
there, and inadvertently trigger NPEs. We originally had the required
validation as a standard Validator implementation, but dealing with this
issue would have required some additional hack on the API that lets a
validator say "not only is there an error here, but don't bother doing any
more validations on it." Much cleaner to have a boolean flag that says
whether this component is required or not.
Also, for any component that extends UIInput, you don't actually have to do
anything to implement this check in your custom component -- it's all done
for you in the base class.
Validation in JSF seems
to be just a mess. I really like JSF overall, but anytime I start
thinking about doing any validation I have to take a couple of shots of
whiskey and bite down on something hard to try and forget about the
I agree :) It's why I tried to write the OptionalValidationFramework :)
However, I think using the MyFaces sandbox subform component or the
ADFFaces subform component is probably a better solution than OVF.
For one thing, OVF doesn't work well with vanilla JSF 1.1 (requires
facelets + 1.1 or requires 1.2).
I don't think subform components will help with this specific
situation, but they'll be helpful in other partial validation
The subform components definitely look like a good step. It's
definitely one thing that I should have included in my list of wants for
the JSF validation system.