How to write a check frame of your own

Source: Internet
Author: User

Parameter checking is necessary for a robust program, so how to verify the parameters is simple and intuitive.

Assuming that there is a user object, we need to make a non-null check on the username password

publicclass User {        private String uname;        private String passwd;    }

Common Verification Logic writing

if (nullnull != user.getPasswd())     returntrue;returnfalse;

This code really works and fits our needs, but this code doesn't read so well, so I made the following changes.

return (nullnull != user.getPasswd());

The revised code is even shorter, but not as beautiful.

Finally we change the code to the following form, only need to add annotations on the properties of the checksum, the last validator can implement the calibration logic we want, both beautiful and intuitive

publicclass User {        @NotNull        private String uname;        @NotNull        private String passwd;    }    publicstaticvoidmain( String[] args ) {        new User();        Validator validator = Validator.newInstance(user);        validator.validate();    }

Next talk about how to implement such a calibration framework

The logic of my implementation is this.

    1. Provides an abstract class that contains abstract methods validate, Init, for writing checksum logic and initialization operations
PublicAbstract  class abstractvalidate<T> {    //Annotationspublic T annotation;//Error hints    PrivateString msg;/** * Author: First line * Explain: validation logic method * @param Object parameter property to be verified * Date 2016/5/25-11:49 * */PublicAbstractBoolean Validate (ObjectObject);/** * Author: First class * Explain: Initialization method, all the checksum subclasses need to write the Init method to set the error message or other custom action after inheriting the abstract class * Date 2016/5/25-11:49 **/PublicAbstractvoid Init ();/** * Author: first-line * Explain: Set default checksum does not pass the hint message * @param annotation Check annotations * @throws Medus Aexception throws an exception when the annotation does not have a value method * Date 2016/5/26-10:44 **/    Privatevoid Enableddefaultmsg (Annotation Annotation) {class<?extendsAnnotation> clazz = Annotationhelper.choice (Annotation);Try{setmsg (string.valueof (Clazz.getmethod ("Value"). Getdefaultvalue ())); }Catch(Nosuchmethodexception e) {Throw NewMedusaexception (e); }    }/** * Author: first-line * Explain: Set the check does not pass the hint message * @param msg Prompt content * Date 2016/5/26-10:26 **/
     public void Setmsg (String msg) { This. msg = msg; }/** * Author: Frontline * explain: Get check return value {@link Medusa} * @param entity {@link enti TY} This parameter contains the annotation for the property, the attribute Field object, and the value of the property * Date 2016/5/25-11:50 **/Public Medusa result (entity entity) {//Set the annotation object to be a validation annotation for the propertyannotation = (T) entity.getannotation ();//Set default prompt informationEnableddefaultmsg (Entity.getannotation ());//Execute initialization methodInit ();//Perform check logicBoolean flag = Validate (Entity.getvalue ());//return check results        return NewMEDUSA (flag, Entity.getfield (), flag? Message.allow: This. msg); }}

2-Create annotations for basic checks such as @NotNull, @Null, @NotEmpty, etc.

These annotations all contain two default values

Class<?> clazz() default NotNullValidate.class;
String value() default Message.NOT_NULL;

Clazz classes implemented for this annotation validation logic
Value is the default error prompt

@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface NotNull {    default NotNullValidate.class;    valuedefault Message.NOT_NULL;}

3-validator checksum, the Clazz default Java class is found by reflection, and the validate method of the class is executed.
The result is correctly marked as true, the error is marked false and the default error prompt is placed in the validation result set

Provides a result(Object object) method to provide a return validation result set

 Public  class Validator {    PrivateObject object; Public StaticValidatornewinstance() {return NewValidator (); } Public StaticValidatornewinstance(Object object) {return NewValidator (object); }Private Validator() {}Private Validator(Object object) { This. Object = object; }/** * Author: First line * Explain: Validation method, which verifies all annotations of the entire object and returns True/false * @param object to be verified * Date 2016/5/25-11:52 **/     Public Boolean Validate(Object object) {set<medusa> Medusaset = result (object); for(Medusa Medusa:medusaset) {if(!medusa.isflag ())return false; }return true; }/** * Author: First line * Explain: Validation method, which verifies all annotations for the entire object, and then returns True/false * The method has no parameters, using {@link Validator#newinstanc E (Object)} method, which can be called directly to get the result of validation * Date 2016/5/25-11:52 **/     Public Boolean Validate() {returnValidate This. Object); }/** * Author: Frontline * Explain: Popup first check result * This method has no parameters, using the {@link validator#newinstance (Object)} method, you can call this method directly to obtain a school Test results * Date 2016/5/25-11:53 **/     PublicMedusaPop() {returnPop This. Object); }/** * Author: Frontline * Explain: Popup first check result * @param object to be verified * Date 2016/5/25-11:53 * * /     PublicMedusaPop(Object object) {set<medusa> Medusaset = result (object);returnMedusaset.iterator (). Next (); }/** * Author: Frontline * Explain: Popup first error check result * @param object to be verified * Date 2016/5/25-11:53 **/     PublicMedusaPopdeny(Object object) {set<medusa> Medusaset = result (object); for(Medusa Medusa:medusaset) {if(!medusa.isflag ())returnMedusa }return NULL; }/** * Author: Frontline * Explain: Popup first error Check result * This method has no parameters, using the {@link validator#newinstance (Object)} method, you can call this party directly method to get Verification results * Date 2016/5/25-11:53 **/     PublicMedusaPopdeny() {returnPopdeny ( This. Object); }/** * Author: first-line * Explain: Gets the checksum return value the method verifies all annotations and returns the validation result set<medusa> * The method has no parameters, using {@link Validator#ne Winstance (Object)} method, you can call this method directly to get the validation results * Date 2016/5/25-11:54 **/     PublicSet<medusa>result() {returnResult This. Object); }/** * Author: first-line * Explain: Get a check return value This method verifies all annotations and returns the validation result set<medusa> * The method needs to validate the object as a parameter, using {@link Vali Dator#newinstance ()} method, you can call this method directly into the validation object to get the check result * @param object to be verified * Date 2016/5/25-11:54 **/     PublicSet<medusa>result(Object object) {Try{//Get annotations and Field,set collections for the object to be verifiedset<entity> EntitySet = Reflectutils.getset (object);//Build an empty hashset to hold the check return resultSet<medusa> Medusaset =NewHashset<medusa> ();//Loop check all field             for(Entity Entity:entityset) {//Get annotationsAnnotation Annotation = Entity.getannotation ();//Get the Annotated classclass<? Extends annotation> clazz = Annotationhelper.choice (Annotation);//Execute annotations The Class.result method pointed to by the Clazz methodObject[] params = {entity}; Object result = Reflectutils.invokemethod ((class<?>) Clazz.getmethod ("Clazz"). Getdefaultvalue (),"Result", params);//Officer results into setMedusaset.add ((Medusa) result); }returnMedusaset; }Catch(Exception e) {Throw NewMedusaexception (e); }    }

4-All validation classes need to inherit the abstract class Abstractvalidate, and write validate logic, and initialize the operation

publicclass NotNullValidate extends AbstractValidate<NotNull> {    publicboolean validate(Object object) {        returnnull != object;    }    publicvoid init() {        this.setMsg(annotation.value());    }}

5-scalability, although the basic validation annotations, but normal development may require custom business annotations, in order to write their own business annotations, only need to create their own annotations, the Clazz point to their own validation class, and Officer class inheritance abstract class Abstractvalidate, Writing the checksum logic, here is a annotationhelper class that loads the annotations under the specified package, which can be configured and implemented to allow developers to customize annotations.

Public     class annotationhelper {//base_package all class collections under Package Private Static set<Class<?>        >Annotation_set;    Initializes the annotated package path to be loaded private final static String Base_package = "Org.yxs.medusa.annotation"; Annotated class map set corresponding to annotation private static map<Annotation, Class<? extends Annotation>> annotation_class_set = new HashMap<Annotation, Class<? extends Annotation>> (); Static {Loadannotation (Base_package); }/** * Author: Frontline * Explain: Initialize load all base check annotations class * @param packagename package path to load * Date 2016/5 /25-11:45 **/    Private Staticvoid Loadannotation (String packagename) {annotation_set = Classutil.getclassset (PackageName); }/** * Author: Frontline * Explain: Select the check type of the attribute (all annotations under the base package) Note * @param Field object property * Date 2016/5/25-1 1:46 **/     Public StaticAnnotation Choice (Field field) { for( Class<?> Clazz : Annotation_set) {Class<? extends Annotation> castclazz = (Class<? extends Annotation>) clazz; if (field. isannotationpresent (castclazz)) {Annotation Annotation = field.getannotation (Castclazz); Annotation_class_set.put (ANNOTATION, Castclazz);returnAnnotation }        }return NULL; }/** * Author: first-line * Explain: Based on annotations annotation get the class of the note for reflection execution method * @param annotation Annotations * Date 2016/5/25-11:47 **/     Public Static  Class<? extends Annotation> Choice(Annotation Annotation) {        returnAnnotation_class_set.get (ANNOTATION); }}

The above is only part of the code, personal writing is too poor, expression can not, the source, interested can see.

Please stab me hard https://github.com/smallcham/medusa.git

Finally, the catalogue map

And the speed comparison with the Hibernate-validtor frame.

The same check is half as fast as hibernate-validator.

How to write a check frame of your own

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.