You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@myfaces.apache.org by Jurgen Lust <Ju...@UGent.be> on 2006/02/25 15:30:47 UTC

validation in model classes with PropertyVetoException

Hi,

I have never really felt good about the validation framework of JSF (and 
Struts for that matter). The problem is that you are forced to put 
validation logic into your view layer, which in the case of JSF means 
polluting your jsp with validator tags.
This becomes especially problematic when you have more than one GUI for 
your application, because then you have to duplicate the validation logic.

What I would prefer is to be able to do validations JavaBeans-style, 
meaning I want to put my validation logic inside the setters of the 
model classes, throwing PropertyVetoExceptions when the validation 
fails. That way, your model classes will never be in an inconsistent state.

I have been working on way to do this in MyFaces. It involves 
registering a custom PropertyResolver (thanks to Jan Dockx for this hint 
:-) ) and a small change to the UIInput class.

The custom PropertyResolver checks if the thrown Exception is a 
PropertyVetoException, and then wraps it in an EvaluationException, so 
as to be JSF spec compliant:

        } catch (Exception e) {

            if (e instanceof PropertyVetoException)

            {

                PropertyVetoException pve = (PropertyVetoException) e;

                throw new EvaluationException(pve.getMessage(), pve);

            } else {

                throw new EvaluationException("Exception setting value of index "

                        + index + " of bean " + base.getClass().getName(), e);

            }

        }

The UIInput needs a change in the updateModel method. In the current myfaces implementation
the UIInput catches all runtime exceptions and adds an error message with key CONVERSION_MESSAGE_ID
to the FacesContext.
In order for my PropertyVetoException message to be displayed, I have to check if the original
cause of the RuntimeException happens to be a PropertyVetoException, in which case the FacesMessage
contains the message of the PropertyVetoException.

I don't think that this change would compromise the JSF spec compliance of myfaces, and the default
behaviour would not change unless you register that custom PropertyResolver. Therefore I would like
to suggest applying this change to the myfaces sourcetree.

What do you think?

Kind regards,

Jurgen


Re: validation in model classes with PropertyVetoException

Posted by Jurgen Lust <Ju...@UGent.be>.
>   <h:inputText value="#{myBean.foo}"/>
>
> ... and then have:
>
>   /**
>    * @greaterThan 5
>    * @lessThan     15
>    */
>   public int getFoo()  { ... }
>
> This seems the right way to go;  PropertyVetoExceptions, not so
> much.
>   
That would indeed be the ideal way, but we are clearly not there yet.
There is an article about this on the Sun Developer Network:
http://java.sun.com/developer/technicalArticles/J2SE/constraints/annotations.html

In the meantime, it would be nice if we can work with what we do have. 
In many cases, the JSF validation framework is very good, but I prefer 
having my constraints enforced in one central place, the model classes.

> There's also a more basic problem with the mechanics of your
> suggestion:  you're moving your validation out of the Process Validation
> phase and into Update Model.  That's a *huge* change, and not
> one I'd recommend.  For one thing, you can't roll back updateModels()
> that have already succeeded, so you've ended with a partially valid
> set of values added to the model
>   
True. That is a definite drawback of this approach. However, it would be 
nice if the developer could choose this approach, which is what my 
suggestion allows: It allows you to show the message of the 
PropertyVetoException, whereas the current implementation catches all 
exceptions from the model and shows a generic error message in the browser.
If you want the default behaviour, no problem, but if you want the 
PropertyVetoException alternative, just plugin the custom PropertyResolver.

I'm preparing a patch now, which I'll post on JIRA so you can testdrive 
it if you want.


Jurgen

Re: validation in model classes with PropertyVetoException

Posted by Adam Winer <aw...@gmail.com>.
I think the complaint about the validation framework of
JSF is only half right.

It's bad that validation rules are specified in the view,
and especially bad that they're specified in the actual
JSP.

However, it's absolutely correct that validation *happens*
in the view.   For example, how are you going to do
Javascript validation in the client if the information
about validation rules is entirely buried in the model layer?

What JSF is missing is a way to automatically derive
its validation from metadata exposed by the model - e.g.,
why not have:

  <h:inputText value="#{myBean.foo}"/>

... and then have:

  /**
   * @greaterThan 5
   * @lessThan     15
   */
  public int getFoo()  { ... }

This seems the right way to go;  PropertyVetoExceptions, not so
much.

There's also a more basic problem with the mechanics of your
suggestion:  you're moving your validation out of the Process Validation
phase and into Update Model.  That's a *huge* change, and not
one I'd recommend.  For one thing, you can't roll back updateModels()
that have already succeeded, so you've ended with a partially valid
set of values added to the model

-- Adam




On 2/25/06, Jurgen Lust <Ju...@ugent.be> wrote:
> Hi,
>
> I have never really felt good about the validation framework of JSF (and
> Struts for that matter). The problem is that you are forced to put
> validation logic into your view layer, which in the case of JSF means
> polluting your jsp with validator tags.
> This becomes especially problematic when you have more than one GUI for
> your application, because then you have to duplicate the validation logic.
>
> What I would prefer is to be able to do validations JavaBeans-style,
> meaning I want to put my validation logic inside the setters of the
> model classes, throwing PropertyVetoExceptions when the validation
> fails. That way, your model classes will never be in an inconsistent state.
>
> I have been working on way to do this in MyFaces. It involves
> registering a custom PropertyResolver (thanks to Jan Dockx for this hint
> :-) ) and a small change to the UIInput class.
>
> The custom PropertyResolver checks if the thrown Exception is a
> PropertyVetoException, and then wraps it in an EvaluationException, so
> as to be JSF spec compliant:
>
>         } catch (Exception e) {
>
>             if (e instanceof PropertyVetoException)
>
>             {
>
>                 PropertyVetoException pve = (PropertyVetoException) e;
>
>                 throw new EvaluationException(pve.getMessage(), pve);
>
>             } else {
>
>                 throw new EvaluationException("Exception setting value of index "
>
>                         + index + " of bean " + base.getClass().getName(), e);
>
>             }
>
>         }
>
> The UIInput needs a change in the updateModel method. In the current myfaces implementation
> the UIInput catches all runtime exceptions and adds an error message with key CONVERSION_MESSAGE_ID
> to the FacesContext.
> In order for my PropertyVetoException message to be displayed, I have to check if the original
> cause of the RuntimeException happens to be a PropertyVetoException, in which case the FacesMessage
> contains the message of the PropertyVetoException.
>
> I don't think that this change would compromise the JSF spec compliance of myfaces, and the default
> behaviour would not change unless you register that custom PropertyResolver. Therefore I would like
> to suggest applying this change to the myfaces sourcetree.
>
> What do you think?
>
> Kind regards,
>
> Jurgen
>
>