Lenik
Lenik

Reputation: 14458

Validate arbitrary objects in JSF?

So, you can validate input using JSR-303 annotations on the binding bean property:

class Ticket {
    @MinAge(18)
    Person person;
}

class Person {
    @Min(1) @Max(100)
    int age;
}

<p:inputText id="age" value="#{bean.ticket.person.age}" />

Here, the property Person.age is validated (between 1..100) with no problem.

The problem is, I want to validate the outer instance (person.age >= 18). But how to make the property bean.ticket.person be known to validation?

I want something like:

<p:inputText id="age" value="#{bean.ticket.person.age}">
    <f:validate value="#{bean.ticket.person}" />
</p:inputText>

Or:

<p:inputText id="age" value="#{bean.ticket.person.age}">
    <f:validator id="jsr303-validator" value="#{bean.ticket.person}" />
</p:inputText>

The problem is, I can't pass a value to <f:validator />. I want to add extra properties to the validation process, more then only the inputs appeared on the page.

P.S. This is a simplified example, the real application is:

...
<p:inputText id="principalLabel" value="${activeACL.principal.label}" readonly="true" />
<p:commandButton value="Choose..." onclick="choosePrincipalDialog.show()" />
...
<p:commandButton value="Save" action="${bean.saveACL}" oncomplete="editACLDialog.hide()" update="index" />

And activeACL of type ACL_DTO:

class ACL_DTO {
    ...
    @IdRequired
    Principal_DTO principal;
}

Here, choosePrincipalDialog's actionListener will implicit change the ${activeACL.principal.id}, which is initially null. IdRequired is a custom constraint which constrains an object's id member property is not null or -1.

Though, I can change to use @NotNull on the id property, and add a hidden-input to enable the validation on the id:

class Principal_DTO {
    ...
    @NotNull
    @Min(0)
    Long id;
}

...
<h:inputHidden id="principalId" value="${activeACL.principal.id}" />
<h:inputText id="principalLabel" ...

But, in this way I can't reuse the validation messages any more. Give message like "This string should not be null", "This value should not be -1" to the user seems meaningless.

Upvotes: 2

Views: 805

Answers (1)

1337
1337

Reputation: 338

Firstly, I think that you should make sure to use the beans only as a place where you get your input available. After that, you assign the value to the model. In my opinion the beans should not be used directly as a model but rather as a web-form-backing beans (Every web form has different bean).

Secondly, I agree that you you come across scenarios where you have dependency to other data to preform the validation (e.g. If the user selected US as a country, the postcode etc. should not be left empty). You can have a look at here how to implement custom annotation: Cross field validation with Hibernate Validator (JSR 303)

If you do not use bean validation you can always implement a custom validator class or even define a validation method directly in the bean: http://docs.oracle.com/javaee/6/tutorial/doc/bnavb.html#bnave

Upvotes: 1

Related Questions