一、应用场景

页面表单有很多字段需要提交,因此使用注解校验的方式针对pojo的属性进行校验 因此使用javax标准以及org.hibernate的validator的注解校验

二、依赖

        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.1.0.Final</version>
        </dependency>

 javax的validation是Java定义的一套基于注解的数据校验规范,目前已经从JSR 303的1.0版本升级到JSR 349的1.1版本,再到JSR 380的2.0版本(2.0完成于2017.08),已经经历了三个版本。JSR只是一项标准,它规定了一些校验注解的规范,但没有实现,比如@Null、@NotNull、@Pattern等,它们位于 javax.validation.constraints这个包下。

而hibernate validator是对这个规范的实现,并增加了一些其他校验注解,如 @NotBlank、@NotEmpty、@Length等,它们位于org.hibernate.validator.constraints这个包下

 项目使用了Spring Boot,hibernate validator框架已经集成在 spring-boot-starter-web中,所以无需再添加其他依赖。如果不是SpringBoot项目需要引入。

        <!-- hibernate validator-->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.2.0.Final</version>
        </dependency>

三、注解说明

1.正则表达式@Pattern注解只用于String类型的字段上。数字类型的可用@Range注解。
2.需要在Controller中请求对象或者参数前加@Validated或@Valid注解一起使用


@Validated和@Valid注解区别不是很大,一般情况下任选一个即可,区别如下:

 

注解@Validated @Valid
所属的包 属于org.springframework.validation.annotation包下的,是spring提供的属于javax.validation包下,是jdk给提供的
是否支持分组和排序


虽然@Validated比@Valid更加强大,在@Valid之上提供了分组功能和验证排序功能,不过在实际项目中一直没有用到过 。Hibernate-validate框架中的注解是需要加在实体中一起使用的


四、代码实现

package cc.jz.basic.domain;

import cc.jz.common.annotation.Dict;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.ToString;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;

/**
 * @Description: JzIsolationTec实体类
 * @Author: wj
 * @CreateDate: Created in  2022-01-20 17:42:32
 * @Modify By:
 * @Version: 1.0
 */
@Data
@ToString
public class JzIsolationTec implements Serializable {
    private static final long serialVersionUID = 436485683104282899L;

    /**
     * 工艺ID
     */
    private Integer id;

    /**
     * 产品规格
     */
    @NotBlank(message = "产品规格不能为空")
    @Size(min = 0, max = 32, message = "产品规格长度不能超过32个字符")
    private String productSpec;

    /**
     * 测试电压
     */
    @Min(0)
    private Integer testVoltage;

    /**
     * 测试时长
     */
    @Min(0)
    private Integer testDura;

    /**
     * 充电时长
     */
    @Min(0)
    private Integer chargeDura;

    /**
     * 放电时长
     */
    @Min(0)
    private Integer dischDura;

    /**
     * 基准阻值
     */
    @Min(0)
    private Integer refResist;

    /**
     * 基准阻值单位
     */
    @NotNull(message = "基准阻值单位不允许为空")
    @Dict(type = "resist_unit")
    private Integer resistUnit;

    /**
     * 执行标准
     */
    @NotBlank(message = "执行标准不能为空")
    @Size(min = 0, max = 50, message = "产品规格长度不能超过32个字符")
    private String execStd;

    /**
     * 工序名称id
     */
    @NotNull(message = "工序名称不允许为空")
    @Dict(type = "process_id")
    private Integer processId;
}
    @Log(title = "新增JzIsolationTec", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@Validated @RequestBody JzIsolationTec jzIsolationTec) {
        return toAjax(jzIsolationTecService.insertJzIsolationTec(jzIsolationTec));
    }

五、自定义注解

package cc.jz.common.annotation;

import cc.jz.common.valid.DictValidator;

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;

/**
 * @Description:
 * @Author: wj
 * @CreateDate: 11:30 2022/1/26
 * @Modify By:
 * @Version: 1.0.0
 */
@Documented
// 标明这个校验注解是使用哪个校验器进行校验的,在这里指定或者在初始化的时候指定
@Constraint(validatedBy = {DictValidator.class})
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})  // 作用位置
@Retention(RUNTIME)  // 运行时机
public @interface Dict {
    String type() default "";

    //    必须要,否则会报错
    String message() default "请检查业务数据字典是否正确配置";

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

    Class<? extends Payload>[] payload() default {};
}
@Constraint指定校验器时,注释上说也可以初始化指定,但是我一直没有找到方法,如果有哪位大佬清楚的,告知下我,感激不尽。
package cc.jz.common.valid;

import cc.jz.common.annotation.Dict;
import cc.jz.common.utils.ServiceDictUtil;
import lombok.extern.slf4j.Slf4j;

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

/**
 * @Description:
 * @Author: wj
 * @CreateDate: 11:36 2022/1/26
 * @Modify By:
 * @Version: 1.0.0
 */
@Slf4j
public class DictValidator implements ConstraintValidator<Dict, Integer> {

    private String type;

    @Override
    public void initialize(Dict constraintAnnotation) {
        this.type = constraintAnnotation.type();
    }

    @Override
    public boolean isValid(Integer value, ConstraintValidatorContext context) {
        if (value != null) {
            String dictLabel = ServiceDictUtil.getServiceDictLabel(this.type, value);
            if (dictLabel == null || "".equals(dictLabel)) {
                return false;
            }
        }
        return true;
    }
}

代码实现中使用了这个@Dict(type = "dev_type")。开发人员配置成数据字典类型,前端传Dict的值,通过这个注解进行检验。一定要加在是数据字典的字段上。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐