2011-04-05

RichFaces 4: JSR 303 Validation

RichFaces 4 is out! In this article I will demonstrate one of the new features - JSR 303 validation with RichFaces 4.

RichFaces supports JSF 2, so I decided to write a small sample app that takes advantage of other JSF 2 goodies as well. Download the source code of this sample Maven 3 application that runs on JBoss 6 and see these in action (in simple action):
  • standard JSR 303 validation
  • custom JSR 303 validation
  • CDI
  • SLF4J
  • JSF 2


Standard JSR-303 Validation


First, look at this sample registration form.

    <h:form>
       <rich:panel>
           <h:panelGrid columns="3">
               <h:outputText value="Email:" />
               <h:inputText id="email" value="#{registration.email}">
                   <rich:validator />
               </h:inputText>
               <rich:message for="email" />

               <h:outputText value="Name:" />
               <h:inputText id="name" value="#{registration.name}">
                   <rich:validator />
               </h:inputText>
               <rich:message for="name" />

               <a4j:commandButton value="Register"
                   action="#{registration.register}" render="length" />
           </h:panelGrid>
       </rich:panel>
   </h:form>

Registration

What’s worth noting is the rich:validator element. That activates JSR 303 validation for that field. Let’s look at the corresponding managed bean.

package me.m1key.rf;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.inject.Inject;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

@ManagedBean
@RequestScoped
public class Registration {
   
   @Inject
   private SessionTracker sessionTracker;

   private String email;
   private String name;

   @NotNull(message = "{rf.email.notNull}")
   @Pattern(message = "{rf.email.pattern}", regexp = "...")
   public String getEmail() {
       return email;
   }

   @NotNull(message = "{rf.name.notNull}")
   @Size(min = 2, message = "{rf.name.size}")
   public String getName() {
       return name;
   }
I spared you the regular expression for email validation. What’s cool about it? This gives you both automatic client-side and server side (in case someone turned off their JavaScript, for instance) validation.


Custom JSR-303 Validation


You might also annotate fields with your own validators. They will be picked up as well.

    @ValidUserName
   public String getName() {
       return name;
   }

@Documented
@Constraint(validatedBy = ValidUserNameValidator.class)
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidUserName {
   String message() default "{rf.validUserName}";

   Class<?>[] groups() default {};

   Class<? extends Payload>[] payload() default {};
}

public class ValidUserNameValidator implements
       ConstraintValidator<ValidUserName, String> {
   
   private Logger log = LoggerFactory.getLogger(ValidUserNameValidator.class);

   private String[] forbiddenNames = { "Michal", "Mikey", "Mickey", "M1key",
           "M1ckey" };

   @Override
   public void initialize(ValidUserName firstUpper) {
       // See JSR 303 Section 2.4.1 for sample implementation.
   }

   @Override
   public boolean isValid(String value, ConstraintValidatorContext context) {
       log.info("Validating");
       
       if (value == null || value.length() == 0) {
           return true;
       }


       return isNotForbidden(value);
   }

   private boolean isNotForbidden(String name) {
       return !isForbidden(name);
   }

   private boolean isForbidden(String name) {
       for (String forbiddenName : forbiddenNames) {
           if (name.equals(forbiddenName)) {
               return true;
           }
       }
       return false;
   }
}

CDI and other goodies


I will describe it in another blog post, but you can check it out already by downloading the source code. What I will also describe is how to add dynamic Ajax statuses for fields which validation takes long time.

6 comments:

  1. You spared us RegExp for email validation, yet I was looking for it. See, it is actually impossible to validate email address with RegExp as there are Internationalized Domain Names (IDNA). And it regards to the whole Domain part, including TLD. It is live as new Local Character based TLD's are being registered... What you could do with RegExp is to only verify that there is at least one character or number before AT sign (@), only one AT sign, at least one character in domain name, a dot separating it from TLD and at least one character in TLD. Of course by character I mean Unicode Character (\p{L} in Java RegExp terms). But it still won't tell you if email is valid...

    ReplyDelete
  2. I don't get it, you can do the same just with JSF 2.0 without richfaces 4 at all, or am I wrong?

    ReplyDelete
  3. Hi Paweł, the regular expression comes straight from the official website tutorial and you can find it here:
    http://richfaces-showcase.appspot.com/richfaces/component-sample.jsf?demo=clientValidation&skin=blueSky
    You can always download the source code for the app described in the article.
    Anyway, I'd agree that this is just basic validation and real validation occurs when you require users to confirm their registration using the code you sent them to the given email.

    Thanks for your comment!

    ReplyDelete
  4. ooblogger, thanks for your insight. The goal of the article was to demonstrate a working Maven application that uses RichFaces 4 and JSF 2.0. There is going to be at least one more article that will focus more on RichFaces 4 - you're right, I haven't shown a lot of it here, good point.

    ReplyDelete
  5. RichFaces 4's JSR 303 validation looks promising! The integration with JSF 2 features like CDI and SLF4J is a great advancement. Your sample app provides a clear illustration. Thanks for sharing!
    New Jersey Order of Protection

    ReplyDelete
  6. "RichFaces 4 JSR 303 Validation" on blog.m1key.me/2011/04 delves into the intricacies of JSR 303 validation within the RichFaces 4 framework, offering valuable insights for developers. The article provides a comprehensive exploration of how JSR 303 validation can be integrated effectively, enhancing the functionality and user experience of RichFaces applications. It's commendable how the author elucidates complex concepts with clarity, making the content accessible to readers with varying levels of expertise. This informative piece serves as a valuable resource for developers seeking to leverage validation techniques in their RichFaces projects. Kudos to the author for sharing such insightful content!
    Domestic Violence Help New Jersey




    ReplyDelete