导入检验的包


    <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>6.0.16.Final</version>
    </dependency>

数据验证

创建书的校验

package com.lanou.demo.bean;

import com.lanou.demo.validator.IDValidations;

import javax.validation.constraints.*;


public class BookBean {

在book类中写校验注解

    private Long bookId;
    //校验书名不能为空
    @NotNull(message = "书名不能为空")
    private String bookName;
    private String author;
    private String publisher;
    //对书的单价校验不能是空,价格在20-100之间
    @DecimalMax(value = "100", message = "价格不超过100元")
    @DecimalMin(value = "20",message = "价格不低于20元")
    @NotNull
    private Float price;
    //设置身份正规范
    //这个注解是自定义的
    @IDValidations(message = "身份证不符和规范")
    private String idCard;
    /*
    正则表达式校验
    正则表达式用来判断某个字符串是否符合某个规则
    或者用来提取一整个字符串中满足某个规则的子串儿
    */
    //为手机号写正则表达式验证
    @Pattern(regexp = "1[345678][0-9]{9}",message = "手机号不符合规格")
    private  String mobile;


    public Long getBookId() {
        return bookId;
    }

    public void setBookId(Long bookId) {
        this.bookId = bookId;
    }

    public String getBookName() {
        return bookName;
    }

    public void setBookName(String bookName) {
        this.bookName = bookName;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getPublisher() {
        return publisher;
    }

    public void setPublisher(String publisher) {
        this.publisher = publisher;
    }

    public Float getPrice() {
        return price;
    }

    public void setPrice(Float price) {
        this.price = price;
    }

    public String getMobile() {
        return mobile;
    }

    public void setMobile(String mobile) {
        this.mobile = mobile;
    }

    public String getIdCard() {
        return idCard;
    }

    public void setIdCard(String idCard) {
        this.idCard = idCard;
    }
}

自定义身份证注解


import com.lanou.demo.untils.IdCardUtils;

import javax.validation.Constraint;
import javax.validation.Payload;
import javax.validation.constraints.NotNull;
import java.lang.annotation.*;

@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(IDValidations.List.class)
@Constraint(
        validatedBy = {IDValidator.class}
)
public @interface IDValidations {

    String message() default "身份证不符合规则";

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

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

    @Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface List {
        IDValidations[] value();
    }
}

创建一个关于id工具类

package com.lanou.demo.untils;

import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;

public class IdCardUtils {
    final static Map<Integer, String> zoneNum = new HashMap<>();
    static {
        zoneNum.put(11, "北京");
        zoneNum.put(12, "天津");
        zoneNum.put(13, "河北");
        zoneNum.put(14, "山西");
        zoneNum.put(15, "内蒙古");
        zoneNum.put(21, "辽宁");
        zoneNum.put(22, "吉林");
        zoneNum.put(23, "黑龙江");
        zoneNum.put(31, "上海");
        zoneNum.put(32, "江苏");
        zoneNum.put(33, "浙江");
        zoneNum.put(34, "安徽");
        zoneNum.put(35, "福建");
        zoneNum.put(36, "江西");
        zoneNum.put(37, "山东");
        zoneNum.put(41, "河南");
        zoneNum.put(42, "湖北");
        zoneNum.put(43, "湖南");
        zoneNum.put(44, "广东");
        zoneNum.put(45, "广西");
        zoneNum.put(46, "海南");
        zoneNum.put(50, "重庆");
        zoneNum.put(51, "四川");
        zoneNum.put(52, "贵州");
        zoneNum.put(53, "云南");
        zoneNum.put(54, "西藏");
        zoneNum.put(61, "陕西");
        zoneNum.put(62, "甘肃");
        zoneNum.put(63, "青海");
        zoneNum.put(64, "新疆");
        zoneNum.put(71, "台湾");
        zoneNum.put(81, "香港");
        zoneNum.put(82, "澳门");
        zoneNum.put(91, "外国");
    }

    final static int[] PARITYBIT = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
    final static int[] POWER_LIST = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10,
            5, 8, 4, 2};

    /**
     * 身份证验证
     *@param certNo  号码内容
     *@return 是否有效 null和"" 都是false
     */
    public static boolean isIDCard(String certNo) {
        if (certNo == null || (certNo.length() != 15 && certNo.length() != 18))
            return false;
        final char[] cs = certNo.toUpperCase().toCharArray();
        //校验位数
        int power = 0;
        for (int i = 0; i < cs.length; i++) {
            if (i == cs.length - 1 && cs[i] == 'X')
                break;//最后一位可以 是X或x
            if (cs[i] < '0' || cs[i] > '9')
                return false;
            if (i < cs.length - 1) {
                power += (cs[i] - '0') * POWER_LIST[i];
            }
        }

        //校验区位码
        if (!zoneNum.containsKey(Integer.valueOf(certNo.substring(0, 2)))) {
            return false;
        }

        //校验年份
        String year = certNo.length() == 15 ? getIdcardCalendar() + certNo.substring(6, 8) : certNo.substring(6, 10);

        final int iyear = Integer.parseInt(year);
        if (iyear < 1900 || iyear > Calendar.getInstance().get(Calendar.YEAR))
            return false;//1900年的PASS,超过今年的PASS

        //校验月份
        String month = certNo.length() == 15 ? certNo.substring(8, 10) : certNo.substring(10, 12);
        final int imonth = Integer.parseInt(month);
        if (imonth < 1 || imonth > 12) {
            return false;
        }

        //校验天数
        String day = certNo.length() == 15 ? certNo.substring(10, 12) : certNo.substring(12, 14);
        final int iday = Integer.parseInt(day);
        if (iday < 1 || iday > 31)
            return false;

        //校验"校验码"
        return certNo.length() == 15 || cs[cs.length - 1] == PARITYBIT[power % 11];
    }

    private static int getIdcardCalendar() {
        GregorianCalendar curDay = new GregorianCalendar();
        int curYear = curDay.get(Calendar.YEAR);
        return Integer.parseInt(String.valueOf(curYear).substring(2));
    }
}

实现自定义注解,



package com.lanou.demo.validator;

import com.lanou.demo.untils.IdCardUtils;
import org.springframework.validation.annotation.Validated;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

//继承ConstraintValidator(写写自定义注解,写要验证的值的类型)

public class IDValidator implements ConstraintValidator<IDValidations, String> {
    @Override
    public void initialize(IDValidations constraintAnnotation) {

    }

    @Override
    public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
        return IdCardUtils.isIDCard(s);
    }
}


在controller中写


   @RequestMapping("/book/create")
   //@Validated 数据校验
   //加上之后就可以对属性进行校验
    public String create(@Validated BookBean book,
                         BindingResult result,Model model){
        //可以通过BindingResult的对象拿到校验信息.
       //注意: 该参数必须紧跟着被检验对象的后面

       if(result.hasErrors()){
           //判断是否有校验错误
         //  result.getFieldError("bookName").getDefaultMessage();

           for (FieldError error : result.getFieldErrors()) {
               //获取校验对象的所有错误信息
               String message = error.getDefaultMessage();
           }
           //可以直接把错误信息的集合放到Model
           model.addAttribute("errors",result.getFieldErrors());
           return  "error";
       }
        return  "success";
    }

在前端把book的错误信息显现出来

这是el表达式的方式
<%
    List<FieldError> errors= (List<FieldError>) request.getAttribute("errors");
    for (FieldError error : errors) {
%>
<p><%= error.getDefaultMessage()%></p>
<%
    }
%>

book验证完

分组验证

登录和注册的验证

创建一个类是做登录和注册的类

package com.lanou.demo.bean;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.hibernate.validator.constraints.Length;

import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import java.util.Date;

public class UserBean {

    //创建两个空的接口
    //这两个接口是用来标记的
    public interface LoginGroup{}
    public interface RegisterGroup{}

    //用户名在登录注册时都需要验证
    @NotBlank(groups = {LoginGroup.class,RegisterGroup.class})
    private String username;

    //密码也在在登录注册时都需要验证
    @JsonIgnore
    @NotBlank(groups = {LoginGroup.class,RegisterGroup.class})
    @Length(min = 6,max = 20,groups = {LoginGroup.class,RegisterGroup.class})
    private  String password;

    //只在注册时验证
    @Pattern(regexp = "1[3-9][\\d]{9}",groups = {RegisterGroup.class})
    private String mobile;

    //只在注册时验证
    @AssertTrue(groups = {RegisterGroup.class})
    private boolean agree;

    //
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private Date birthday;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getMobile() {
        return mobile;
    }

    public void setMobile(String mobile) {
        this.mobile = mobile;
    }

    public boolean isAgree() {
        return agree;
    }

    public void setAgree(boolean agree) {
        this.agree = agree;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
}

在controller中

package com.lanou.demo.controller;

import com.lanou.demo.bean.UserBean;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class UserController {

    //在登录时调用UserBean中的登录验证
    @RequestMapping("/user/login")
    public String login(@Validated(UserBean.LoginGroup.class) UserBean userBean){

        return "success";
    }

    //在注册时调用UserBean中的注册验证
    @RequestMapping("/user/register")
    public String register(@Validated(UserBean.RegisterGroup.class) UserBean userBean){

        return "success";
    }


    //通过异常处理捕获到异常
    //捕获异常,在异常中处理异常,不用去判断
    @ExceptionHandler(BindException.class)
    public  String resolveBingingException(BindException ex){
       //通过异常对象获取到所有的验证错误
        FieldError fieldError = ex.getFieldError();

        return "error";
    }
}

posted on 2019-05-26 14:23  脑抽不要停  阅读(439)  评论(0编辑  收藏  举报