参数校验(javax.validation)学习
一、应用场景
页面表单有很多字段需要提交,因此使用注解校验的方式针对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的值,通过这个注解进行检验。一定要加在是数据字典的字段上。
更多推荐
所有评论(0)