English 中文(简体)
How to create a custom validator in Play Framework 2.0?
原标题:

Play 1.0 comes with a full featured validation framework base on http://oval.sourceforge.net/.

With the release of 2.0, my custom validators do not work anymore.

How does one create custom validator using Play Framework 2.0 ?

最佳回答

In Play 2.0, the validation framework extends beyond the actual validation of the data as it reaches to:

  • Annotations - to easily declare validation contraints using the @ sign
  • Validators - which actually implements to logic behind the validation
  • Messages - to display parametrized error messages (i18 compliant)
  • Finally, HTML helpers - that glue all the previous together

The HTML Helpers are something new to Play 2.0. In 1.x, Play was already pretty good at enforcing a well defined validation framework. It was powerful and easy to use. Yet we still had to wire the HTML form and the validation framework together. This could be a little confusing to the beginner.

With Play 2.0, this is now done automatically.

But let s focus on the answer and provide some guidance: We will create an AllUpperCase validator, that generates an error either when:

  • the input is not a String
  • the input is empty
  • one of the characters is lower-case.

The validator

package myvalidators;

import javax.validation.*;

public class AllUpperCaseValidator 
        extends play.data.validation.Constraints.Validator<Object> 
        implements ConstraintValidator<AllUpperCase, Object> {

    /* Default error message */
    final static public String message = "error.alluppercase";

    /**
     * Validator init
     * Can be used to initialize the validation based on parameters
     * passed to the annotation.
     */
    public void initialize(AllUpperCase constraintAnnotation) {}

    /**
     * The validation itself
     */
    public boolean isValid(Object object) {
        if(object == null)
            return false;

        if(!(object instanceof String))
            return false;

        String s = object.toString();  
        for(char c : s.toCharArray()) {
            if(Character.isLetter(c) && Character.isLowerCase(c))
                return false;
        }

        return true;
    }

    /**
     * Constructs a validator instance.
     */
    public static play.data.validation.Constraints.Validator<Object> alluppercase() {
        return new AllUpperCaseValidator();
    }
}

The first thing you may notice is the import: Play 2.0 indeed complies with JSR 303 - Bean Validation Framework. In this context, the validator needs to implement ConstraintValidator. Which in our case translates into the annotation as class AllUpperCase (which we will introduce in a minute) and T as a generic Object.

The validator is straighforward:
We defined the method public boolean isValid(Object object) that returns a boolean, if true the validation passed. There is also an message id and a method that instanciates the validator.

The Annotation

The class below defines an annotation named @AllUpperCase which takes no parameters but enforces the validation defined previously. Providing details related to the annotation framework is outside the scope of this post.

package myvalidators;

import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;

import javax.validation.*;

@Target({FIELD})
@Retention(RUNTIME)
@Constraint(validatedBy = AllUpperCaseValidator.class)
@play.data.Form.Display(name="constraint.alluppercase")
public @interface AllUpperCase {
    String message() default AllUpperCaseValidator.message;
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

Note how the anotation glues to the other pieces of the puzzle.

  • @Constraint, a JSR 303 annotation, links to the validator
  • @play.data.Form.Display, links the annotation to the play html helpers. Note that the name is important: we are defining a constraint named alluppercase. Play uses this information to call the method public static play.data.validation.Constraints.Validator<Object> alluppercase() on the Validator.
  • Finally note that the default message is set within the anotation interface.

Usage

We now have our custom validator and annotation

import myvalidators.*;
public static class MyData {
    @AllUpperCase
    public String name;
}

Describing the usage is outside the scope of this post, please find a working sample at this URL

问题回答

暂无回答




相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签