Fork me on GitHub

validation-api之hibernate-validator的使用

JSR规范

JSR是Java Specification Requests的缩写,意思是Java规范提案。是指向JCP(Java Community Process,JCP维护的规范包括J2ME、J2SE、J2EE,XML,OSS,JAIN等)提出新增一个标准化技术规范的正式请求。任何人都可以提交JSR,以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准。
JSR规范,JDBC、EJB、NIO、JDBC、JSP、JMX等都是JSR规范中的。

validation-api和hibernate-validator

validation-api只是一套标准,是Java EE6中的一项子规范,JSR规范编号303,叫做BeanValidation,官方参考实现是hibernate-validator。后来又扩展了JSR 349,提出了依赖注入、注解等内容。

hibernate-validator java代码

maven坐标

hibernate-validator中包含了validation-api,所以不用重复引入。

    <!--注解实现校验-->
    <dependency>
      <groupId>javax.el</groupId>
      <artifactId>javax.el-api</artifactId>
      <version>2.2.4</version>
    </dependency>
    <!--  hibernate-validator-->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>5.2.2.Final</version>
    </dependency>

实体类

package com.validation;

import lombok.Data;
import javax.validation.constraints.*;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;

@Data
public class Student implements Serializable {

    @NotNull(message = "名字不能为空")
    private String name;

    @Size(min = 6,max = 30,message = "地址应该在6-30字符之间")
    private String address;

    @DecimalMax(value = "100.00",message = "体重有些超标哦")
    @DecimalMin(value = "60.00",message = "多吃点饭吧")
    private BigDecimal weight;

    private String friendName;

    @AssertTrue
    private Boolean isHaveFriend(){
        return friendName != null?true:false;
    }

    @Future(message = "生日必须在当前时间之前")
    private Date birthday;

    @Pattern(regexp = "^(.+)@(.+)$",message = "邮箱的格式不合法")
    private String email;
}

测试类

package com.validation;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

public class StudentTest implements Serializable {
    //获取验证器工厂
    private static ValidatorFactory factory = Validation.buildDefaultValidatorFactory();

    public static void main(String[] args) {
        Student bean = new Student();
        bean.setName(null);
        bean.setAddress("扬州");
        bean.setBirthday(new Date());
        bean.setFriendName(null);
        bean.setWeight(new BigDecimal(30));
        bean.setEmail("163.com");
        //验证实体数据
        List<String> validate = validate(bean);
        validate.forEach(row -> {
            System.out.println(row.toString());
        });
    }

    /**
     * 验证实体
     * @param t 实体类
     * @return 返回实体类的验证message集合
     */
    public static <T> List<String> validate(T t) {
        Validator validator = factory.getValidator();
        Set<ConstraintViolation<T>> constraintViolations = validator.validate(t);
        List<String> messageList = new ArrayList<>();
        for (ConstraintViolation<T> constraintViolation : constraintViolations) {
            messageList.add(constraintViolation.getMessage());
        }
        return messageList;
    }
}

测试结果
image

Spring MVC集成hibernate-validator

maven坐标

jsr-349,hibernate-validator中包含了validation-api 1.1.0这个接口包,所以不用重复引入。

    <!--注解实现校验,spring mvc可以不引用,但是为了junit使用依然引用-->
    <dependency>
      <groupId>javax.el</groupId>
      <artifactId>javax.el-api</artifactId>
      <version>2.2.4</version>
    </dependency>
    <!--  hibernate-validator-->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>5.2.2.Final</version>
    </dependency>

spring-mvc.xml

HibernateValidator没有使用国际化,配置如下

    <!-- HibernateValidator -->
    <mvc:annotation-driven validator="validator"/>
    <!-- 以下 validator  ConversionService 在使用 mvc:annotation-driven 会 自动注册-->
    <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
        <property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
    </bean>

model类

使用javax.validation的@NotNull、@Pattern、@Size和hibernate.validator的@NotEmpty、@Length等注解,注解中可以用message属性自定义提示。

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

@Data
@TableName(value = "t_admin")
public class TAdmin implements Serializable {

    @TableId(value = "id", type = IdType.AUTO)
    @NotNull(message = "主键不能为null")
    private Integer id;

    @TableField(value = "name")
    @NotEmpty
    @Length(min = 5, max = 20)
    @Pattern(regexp = "[a-zA-Z]{5,20}",message = "只能为5到20位的英文字母")
    private String name;

    @TableField(value = "username")
    @NotEmpty
    @Size(min = 5, max = 20)
    private String username;

    @TableField(value = "password")
    @NotNull
    private String password;
}

Controller层

@Valid或者@Validated注解验证。

    @RequestMapping("/save")
    @ResponseBody
    public Object save(@Valid TAdmin user, BindingResult bindingResult) {
        Map<String, Object> result = new HashMap<String, Object>();
        /*获取BeanValid验证消息*/
        if(bindingResult.hasErrors()) {  //如果有验证出错误
            if(bindingResult.hasErrors()) {
                //获取所有错误
                List<FieldError> errs = bindingResult.getFieldErrors();
                //把所有所处的field和defaultmessage拿出来放入Map中
                Map<String, String> mapErrors = new LinkedHashMap<String, String>();
                for(FieldError err : errs) {
                    mapErrors.put(err.getField(), err.getDefaultMessage());
                }
                result.put("success", false);
                result.put("errors", mapErrors);
                return result;
            }
        }

        boolean r = adminService.save(user);
        result.put("success", true);
        result.put("result", r);
        return result;
    }

测试结果

image
参考:
https://www.cnblogs.com/softidea/p/10072114.html

posted @ 2021-06-23 10:41  秋夜雨巷  阅读(1086)  评论(0编辑  收藏  举报