Hibernate Validation自定义验证规则

一、简介

有时候在做项目的过程中会发现Hibernate Validation提供的验证规则并不能百分百的复合业务需要,就如,在插入数据库时要保证插入进去的某个属性的ID必须要唯一,不能重复插入,类似于表单不能重复提交,,在这个时候,我们就得扩展Validation来实现自己的业务,具体步骤如下:


1、首先定义一个注解

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
/**
 * @version V1.0
 * @Author fendo
 * @ClassName MobileCheck
 * @PackageName 
 * @Description 数据插入ID唯一校验
 * @Data 2017-09-21 10:47
 **/
@Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE })
@Retention(RUNTIME)
//指定验证器
@Constraint(validatedBy = CheckValidator.class)
@Documented
public @interface InsertCheck {

    //默认错误消息
    String message() default "{forbidden.word}";
    //查询的表名
    String tableName() default "";
    String cloumn() default "";
    String sql() default "";
    //分组
    Class<?>[] groups() default { };
    //负载
    Class<? extends Payload>[] payload() default { };
    //指定多个时使用
    @Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE })
    @Retention(RUNTIME)
    @Documented
    @interface List {
        InsertCheck[] value();
    }

}

2、定义一个类实现ConstraintValidator

import com.gz.medicine.common.util.JuheUtil;
import com.gz.medicine.common.util.RegexUtils;
import com.gz.medicine.common.util.SimpleResult;
import com.gz.medicine.common.util.TimeUtil;
import com.gz.medicine.gzyun.health.mapper.HealthyOrderMapper;
import org.apache.commons.collections.map.HashedMap;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.annotation.Annotation;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * @version V1.0
 * @Author fendo
 * @ClassName MobileCheck
 * @PackageName 
 * @Description 扩展Validator
 * @Data 2017-09-21 10:47
 **/
public class CheckValidator implements ConstraintValidator<Annotation, Object> {

    @Autowired
    HealthyOrderMapper healthyordermapper;  //数据库操作Mapper
	
    public static final Logger LOGGER = Logger.getLogger(CheckValidator.class);
    public static final String DATE_CHECK ="((^((1[8-9]\\d{2})|([2-9]\\d{3}))([-\\/\\._])(10|12|0?[13578])([-\\/\\._])(3[01]|[12][0-9]|0?[1-9])$)|(^((1[8-9]\\d{2})|([2-9]\\d{3}))([-\\/\\._])(11|0?[469])([-\\/\\._])(30|[12][0-9]|0?[1-9])$)|(^((1[8-9]\\d{2})|([2-9]\\d{3}))([-\\/\\._])(0?2)([-\\/\\._])(2[0-8]|1[0-9]|0?[1-9])$)|(^([2468][048]00)([-\\/\\._])(0?2)([-\\/\\._])(29)$)|(^([3579][26]00)([-\\/\\._])(0?2)([-\\/\\._])(29)$)|(^([1][89][0][48])([-\\/\\._])(0?2)([-\\/\\._])(29)$)|(^([2-9][0-9][0][48])([-\\/\\._])(0?2)([-\\/\\._])(29)$)|(^([1][89][2468][048])([-\\/\\._])(0?2)([-\\/\\._])(29)$)|(^([2-9][0-9][2468][048])([-\\/\\._])(0?2)([-\\/\\._])(29)$)|(^([1][89][13579][26])([-\\/\\._])(0?2)([-\\/\\._])(29)$)|(^([2-9][0-9][13579][26])([-\\/\\._])(0?2)([-\\/\\._])(29)$))";
    public static final String TIME_CHECK="^([0-1]?[0-9]|2[0-3]):([0-5][0-9])";
    public static final String YYYYMMHHDDMI="^(\\d{4})-(0\\d{1}|1[0-2])-(0\\d{1}|[12]\\d{1}|3[01]) (0\\d{1}|1\\d{1}|2[0-3]):([0-5]\\d{1})$";
    
	private String value;
    private int annotationType;

    @Override
    public void initialize(Annotation annotation) {
        if (annotation instanceof InsertCheck) {
            annotationType = 0;
            InsertCheck ak = (InsertCheck) annotation;
            this.value = ak.sql();
        }
        if (annotation instanceof DateCheck) {
            annotationType = 1;
            DateCheck dk = (DateCheck) annotation;
            this.value = dk.type();
        }
        if (annotation instanceof IdCardCheck) {
            annotationType = 2;
            IdCardCheck ik = (IdCardCheck) annotation;
        }

        if (annotation instanceof MobileCheck) {
            annotationType = 3;
            MobileCheck ik = (MobileCheck) annotation;
        }

    }

    public static void main(String[] args) {

        System.out.println(Pattern.matches("","2017-12-32 09:54"));
    }

    @Override
    public boolean isValid(Object ot, ConstraintValidatorContext constraintValidatorContext) {
        boolean re = false;
        try {
            switch (annotationType) {

                case 0: {
                    try {
                        String key = this.value.substring(this.value.indexOf("{") + 1, this.value.indexOf("}"));
                        Map<String, Object> mp = new HashedMap();
                        mp.put("sql", this.value);
                        mp.put(key, ot);
                        List<Map<String, Object>> li = healthyordermapper.exuSql(mp);
                        System.out.println(li.size());
                        if (li != null && li.size() == 0) {
                            re = true;
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        ;
                    }
                    break;
                }
                case 1: {
                    try {
                        if("YYYY-MM-DD".equals(this.value)){
                            re =Pattern.matches(DATE_CHECK, (String) ot);
                        }
                        if("HH:MI".equals(this.value)){
                            re =Pattern.matches(TIME_CHECK, (String) ot);
                        }
                        if("YYYY-MM-DD HH:MI".equals(this.value)){
                            re =Pattern.matches(YYYYMMHHDDMI, (String) ot);
                        }

                    } catch (Exception e) {
                        e.printStackTrace();
                        ;
                    }
                    break;
                }
                case 2: {
                    try {
                        SimpleResult sr = JuheUtil.getIdcardMsg((String) ot);
                        String code = (String) sr.get("code");
                        if ("000".equals(code)) {
                            re = true;
                        }
                    } catch (Exception e) {
                    }
                    break;
                }
                case 3:{
                    re  = RegexUtils.isMobile((String) ot);
                    break;
                }

            }

        } catch (Exception e) {
            LOGGER.error("校验异常:" + e.getMessage(), e);
        }
        return re;

    }


}

3、使用方式

    /**
     * 出生日期
     */
    @DateCheck(type="YYYY-MM-DD",message="请输入正确的出生日期!!!!")
    @NotEmpty(message="出生日期不能为空!")
    String usrbirth;
	
	 /**
     * 手机号码
     */
    @NotEmpty(message="手机号码不能为空!")
    @MobileCheck(message="请输入正确的手机号!")
    String usrphone;

4、其他一些验证规则

4.1 时间验证

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

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

/**
 * @version V1.0
 * @Author fendo
 * @ClassName MobileCheck
 * @PackageName 
 * @Description 时间验证
 * @Data 2017-09-21 10:47
 **/
@Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE })
@Retention(RUNTIME)
//指定验证器
@Constraint(validatedBy = CheckValidator.class)
@Documented
public @interface DateCheck {

    //默认错误消息
    String message() default "YYYY-MM-DD";
    //查询的表名
    String type() default "YYYY-MM-DD";
    //分组
    Class<?>[] groups() default { };

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

    //指定多个时使用
    @Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE })
    @Retention(RUNTIME)
    @Documented
    @interface List {
        DateCheck[] value();
    }

}

4.2 身份证验证

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

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

/**
 * @version V1.0
 * @Author fendo
 * @ClassName MobileCheck
 * @PackageName 
 * @Description 身份证验证
 * @Data 2017-09-21 10:47
 **/
@Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE })
@Retention(RUNTIME)
//指定验证器
@Constraint(validatedBy = CheckValidator.class)
@Documented
public @interface IdCardCheck {

    //默认错误消息
    String message() default "身份证格式错误.";
    //查询的表名
    //分组
    Class<?>[] groups() default { };

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

    //指定多个时使用
    @Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE })
    @Retention(RUNTIME)
    @Documented
    @interface List {
        IdCardCheck[] value();
    }

}

4.3 手机号验证

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

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

/**
 * @version V1.0
 * @Author fendo
 * @ClassName MobileCheck
 * @PackageName com.gz.medicine.gzyun.health.vaild
 * @Description 手机号校验
 * @Data 2017-09-21 10:47
 **/
@Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE })
@Retention(RUNTIME)
//指定验证器
@Constraint(validatedBy = CheckValidator.class)
@Documented
public @interface MobileCheck {
    String message() default "手机号格式错误";
    Class<?>[] groups() default { };
    Class<? extends Payload>[] payload() default { };
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值