My JSF Books/Videos My JSF Tutorials OmniFaces/JSF PPTs
JSF 2.3 Tutorial
JSF Caching Tutorial
JSF Navigation Tutorial
JSF Scopes Tutorial
JSF Page Author Beginner's Guide
OmniFaces 2.3 Tutorial Examples
OmniFaces 2.2 Tutorial Examples
JSF Events Tutorial
OmniFaces Callbacks Usages
JSF State Tutorial
JSF and Design Patterns
JSF 2.3 New Features (2.3-m04)
Introduction to OmniFaces
25+ Reasons to use OmniFaces in JSF
OmniFaces Validators
OmniFaces Converters
JSF Design Patterns
Mastering OmniFaces
Reusable and less-verbose JSF code

My JSF Resources ...

Java EE Guardian
Member of JCG Program
Member MVB DZone
Blog curated on ZEEF
OmniFaces is an utility library for JSF, including PrimeFaces, RichFaces, ICEfaces ...

[OmniFaces Utilities] - Find the right JSF OmniFaces 2 utilities methods/functions

Search on blog

Petition by Java EE Guardians

Twitter

vineri, 3 aprilie 2015

OmniFaces <o:validateBean> to control bean validation on a per-UICommand sample

In this post, you can see how to use OmniFaces, <o:validateBean> validator to control bean validation on a per-UICommand (it can be used on a per-UIInput also).
So, let's build a scenario to emphasize a use case of <o:validateBean> on a per-UICommand. Let's suppose that we have a simple form that contains two input fields representing the name and the e-mail of an website member or admin. Next to these inputs, we have two buttons, one with label Contact Member and another one with label Contact Admin. When the user clicks on the first button, he will "contact" the specified website member, and when he clicks on the second button, he will "contact" the specified website admin. The form is:

<h:form>           
  Name: <h:inputText value="#{contactBean.name}"/>               
  E-mail: <h:inputText value="#{contactBean.email}"/>                     
  <h:commandButton value="Contact Member" action="contact_member"/>
  <h:commandButton value="Contact Admin" action="contact_admin"/>
</h:form>

For a website member/admin the name input should not violate any of the next validation constrains (snipped from Contact Bean):

@Size.List({
  @Size(min = 3, max = 20, message = "(member)# please enter a valid name (between 3-20 characters)", 
        groups = beans.MemberContactValidationGroup.class),
  @Size(min = 6, max = 10, message = "(admin)# please enter a valid name (between 6-10 characters)", 
        groups = beans.AdminContactValidationGroup.class)
})
@Pattern(regexp = "(admin)[a-zA-Z0-9]*", message = "(admin)# please enter a valid name (it should start with admin...)", 
         groups = beans.AdminContactValidationGroup.class)
private String name;

For a website member/admin the email input should not violate any of the next validation constrains (snipped from Contact Bean):

@Size(min = 1, message = "Please enter the e-mail !")
@Pattern.List({
  @Pattern(regexp = "[a-zA-Z0-9]+@[a-zA-Z0-9]+\\.[a-zA-Z0-9]+", message = "(member)# please enter a valid formated e-mail", 
           groups = beans.MemberContactValidationGroup.class),
  @Pattern(regexp = "(admin)+@[a-zA-Z0-9]+\\.[a-zA-Z0-9]+", message = "(admin)# please enter a valid e-mail (it should start with admin@...)", groups = beans.AdminContactValidationGroup.class)
})
private String email;

So, in group, MemberContactValidationGroup we have added the constrains for the members of a website, and, in the AdminContactValidationGroup group we have added the constraints for the admins of the website. Moreover, we have a constraint over email in the default group.

Next, we should "attached" these constraints to the name and email inputs, but, we need to obtain the following functionality:

·         if the user clicks on the Contact Member button, then the validation should take into account only constraints from default group and from MemberContactValidationGroup, and ignore the constraints from AdminContactValidationGroup
·         if the user clicks on the Contact Admin button, then the validation should take into account only constraints from default group and from AdminContactValidationGroup, and ignore the constraints from MemberContactValidationGroup

In a naive approach, you may think that the below snippet will do the job:

<h:form>        
  <f:validateBean validationGroups="javax.validation.groups.Default, 
                                    beans.MemberContactValidationGroup,                                                                                                         beans.AdminContactValidationGroup">
    Name: <h:inputText value="#{contactBean.name}"/>               
    E-mail: <h:inputText value="#{contactBean.email}"/>           
  </f:validateBean>
  <h:commandButton value="Contact Member" action="contact_member"/>
  <h:commandButton value="Contact Admin" action="contact_admin"/>           
</h:form>

Well, it doesn't work! In the above snippet of code we attached all constraints (member + admin constrains) to the name and email inputs. This means that it just doesn't matter if you click on Contact Member or on Contact Admin button, because all constrains will be applied (obviously, not desirable). Finding a solution will end up in boilerplate code, because it will required a bunch of tags, EL expressions, conditions, server-side code, etc. Most likely, at the end, our form will look like a total mess.

OmniFaces provides a custom validator that can help us to solve these kind of tasks. This validator is exposed to JSF page authors via <o:validateBean> tag. Among its features, it can be used to control bean validation on a per-UICommand, which is perfect for our use case. So, we just remove the <f:validateBean>, and add <o:validateBean> nested in <h:commandButton>, as below:

xmlns:o="http://omnifaces.org/ui"
...
<h:form>        
  Name: <h:inputText value="#{contactBean.name}"/>               
  E-mail: <h:inputText value="#{contactBean.email}"/>                     
  <h:commandButton value="Contact Member" action="contact_member">
    <o:validateBean validationGroups="javax.validation.groups.Default, beans.MemberContactValidationGroup"/>
  </h:commandButton>
  <h:commandButton value="Contact Admin" action="contact_admin">
    <o:validateBean validationGroups="javax.validation.groups.Default, beans.AdminContactValidationGroup"/>
  </h:commandButton>          
</h:form>

Done! Now, everything will work as expected. Complete source code on GitHub.

Check OmniFaces Showcase to see more details about <o:validateBean>. Beside an example that allows the developer to control bean validation on a per-UICommand, you can see an example of how to use <o:validateBean> to validate a given bean at the class level.

Niciun comentariu :

Trimiteți un comentariu

JSF BOOKS COLLECTION

Postări populare

OmniFaces/JSF Fans

Follow by Email

Visitors Starting 4 September 2015

Locations of Site Visitors