Spring Validation

概念

在原先的编码中,我们如果要验证前端传递的参数,一般是在接受到传递过来的参数后,手动在代码中做 if-else 判断,这种编码方式会带来大量冗余代码,十分的不优雅。


因此,推出了用注解的方式,来代替手动判断的方式,让编码更加的简洁。

使用方式

引入注解:
一般在

        <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

依赖中会有相关依赖,如果没有的话,可以手动引入下面的依赖。

    <dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.18.Final</version>
<scope>compile</scope>
</dependency>

get

针对 get 方式的请求,我们的请求参数直接放在参数列表里,因此直接在参数列表里加上想要验证的注解即可。

  @GetMapping("xss")
public void xssGet(@RequestParam("xss1") @Size(min = 1,max = 15,message = "长度不对") String xss, HttpServletRequest request) { }

在方法中,需要验证 xss 参数是否符合长度规范,即长度在 1-15 个字符之间,如果不对,则会提示出信息:长度不对。

post

在 post 方法中,传递的参数一般比较多,因此大多数情况下,采用的是传递的实体类的形式,然后用 json 的形式来传递数据,在这种情况下,使用的方式为构建一个实体类,然后在实体类的属性上添加注解来做。

@Data
public class SaveEmployeeParam implements Serializable {
private static final long serialVersionUID = 8176094330224588795L; @NotEmpty
private String Id; @Size(max = 15, message = "名称必填,且最多为15个汉字")
private String nickname; @PhoneValidationAnnotation
private String phone;
} @PostMapping
public ResultEntity saveEmployee( @Valid @RequestBody SaveEmployeeParam saveEmployeeParam) {
employeeService.saveEmployee(saveEmployeeParam);
return ResultEntity.success();
}

通过该方式,在验证 SaveEmployeeParam 时,框架就会自动在接受参数时,验证实体类中的值是否符合注解定义的规范。


在这里,就会验证 id 不能为空,nickname 的长度最多15个字符,以及我在手机号上添加了一个自定义注解,在确保其符合手机号规范。

分组校验

有时,我们的一个实体类可能会在多种情况下使用,而又不想每种情况都定义一个实体类,则可以采用分组校验的方式,在不同的情况下,采用不同的校验方案。


首先自定义几种不同情况下的接口:

public interface Create {
} public interface Update {
}

然后在指定的 pojo 上指定不同的情况下的策略:

@Data
public class Demo {
@Size(max = 15, groups = Create.class)
@Size(max = 10, groups = Update.class)
private String name; @Max(value = 100, groups = Create.class)
@Max(value = 20, groups = Update.class)
private Integer age;
}

最后,在不同的方法上,根绝业务需要指定使用不同的策略即可:

    @PostMapping("xss3")
public String xssPost(@Validated({Create.class}) @RequestBody Demo xss3) {
return JSON.toJSONString(xss3);
} @PutMapping("xss4")
public String xssUpdate(@Validated({Update.class}) @RequestBody Demo xss4) {
return JSON.toJSONString(xss4);
}

在这种情况下,则在执行 xssPost() 方法时,采用是 Create 的执行方案,在执行 xssUpdate() 方法时,采用的是 Update 方案。

提供的全部注解

JSR提供的校验注解:
@Null 必须为 null
@NotNull 必须不为 null
@AssertTrue 必须为 true
@AssertFalse 必须为 false
@Min(value) 大于等于 给定数字
@Max(value) 小于等于 给定数字
@DecimalMin(value) 大于等于 给定数值
@DecimalMax(value) 小于等于 给定数字
@Size(max=, min=) 集合或字符串长度在指定范围内
@Digits 指定整数部分和小数部分可以接受的最大位数
@Past 必须为一个过去的时间
@Future 必须为一个未来的时间
@Pattern(regex=,flag=) 给定字符串符合正则表达式
Hibernate Validator提供的校验注解
@NotBlank(message =) 非 null,且长度必须大于 0
@Email 符合电子邮箱规范
@Length(min=,max=) 字符串长度在给定范围内
@NotEmpty 字符串或集合 非空
@Range(min=,max=,message=) 数字或字符串表示的数字在指定范围内

自定义

当业务需要一些官方没有提供的校验类型的话,为了方便,我们就需要考虑使用自定义注解的形式了。


这里,我们采用手机号的形式来演示一下,首先我们自定义一个注解:

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {PhoneValidation.class})
public @interface PhoneValidationAnnotation {
String message() default "手机号不符合规范格式";
}

在代码中,我们定义了默认的错误提示信息。


然后,我们写一个实现类,来具体实现注解所要表达的含义:

public class PhoneValidation implements ConstraintValidator<PhoneValidationAnnotation, String> {
String phonePattern;
Pattern compile; @Override
public void initialize(PhoneValidationAnnotation constraintAnnotation) {
phonePattern = "1[3456789]\\d{9}";
compile = Pattern.compile(phonePattern);
} @Override
public boolean isValid(String value, ConstraintValidatorContext context) {
return compile.matcher(value).matches();
}
}

在代码中,我们创建了一个类,实现 ConstraintValidator 接口,并重写其的初始化方法和验证方法,这样,在验证参数的时候,其就会自动调用相关的方法来验证传递的是否正确。

// 注解:要校验的数字在给定的集合中

// 定义接口
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {EnumValidation.class})
public @interface EnumValidationAnnotation {
long[] limitValue() default {};
} // 具体实现
public class EnumValidation implements ConstraintValidator<EnumValidationAnnotation, Long> { private long[] longValues; @Override
public void initialize(EnumValidationAnnotation constraintAnnotation) {
longValues = constraintAnnotation.limitValue();
} @Override
public boolean isValid(Long value, ConstraintValidatorContext context) {
for (long longValue : longValues) {
if (value == longValue) {
return true;
}
}
return false;
}
}

Spring Validation-用注解代替代码参数校验的更多相关文章

  1. java自定义注解实现前后台参数校验

    2016.07.26 qq:992591601,欢迎交流 首先介绍些基本概念: Annotations(also known as metadata)provide a formalized way ...

  2. Spring Boot实现通用的接口参数校验

    Spring Boot实现通用的接口参数校验 Harries Blog™ 2018-05-10 2418 阅读 http ACE Spring App API https AOP apache IDE ...

  3. 利用 Bean Validation 来简化接口请求参数校验

    团队新来了个校招实习生静静,相互交流后发现竟然是我母校同实验室的小学妹,小学妹很热情地认下了我这个失散多年的大湿哥,后来... 小学妹:大湿哥,咱们项目里的 Controller 怎么都看不到参数校验 ...

  4. spring mvc +@Valid +@RequestBody 来做参数校验返回400,并且不显示具体message 如何解决

    参考文档: https://www.oschina.net/question/115867_2282711   谢谢原作者

  5. 使用spring validation完成数据后端校验-自定义校验的注解-判断是否为空

    引入依赖 我们使用maven构建springboot应用来进行demo演示. <dependencies> <dependency> <groupId>org.sp ...

  6. 使用Spring Validation优雅地校验参数

    写得好的没我写得全,写得全的没我写得好 引言 不知道大家平时的业务开发过程中 controller 层的参数校验都是怎么写的?是否也存在下面这样的直接判断? public String add(Use ...

  7. 使用spring validation完成数据后端校验

    前言 数据的校验是交互式网站一个不可或缺的功能,前端的js校验可以涵盖大部分的校验职责,如用户名唯一性,生日格式,邮箱格式校验等等常用的校验.但是为了避免用户绕过浏览器,使用http工具直接向后端请求 ...

  8. Spring validation 后端校验【转】

    本文来自 下一秒升华 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/u013815546/article/details/77248003?utm_source=co ...

  9. Spring Boot 2.x基础教程:JSR-303实现请求参数校验

    请求参数的校验是很多新手开发非常容易犯错,或存在较多改进点的常见场景.比较常见的问题主要表现在以下几个方面: 仅依靠前端框架解决参数校验,缺失服务端的校验.这种情况常见于需要同时开发前后端的时候,虽然 ...

随机推荐

  1. 牛客挑战赛40 VMware和基站 set 二分 启发式合并 区间覆盖

    LINK:VMware和基站 一道 做法并不常见的题目 看起来很难写 其实set维护线段就可以解决了. 容易想到 第二个操作借用启发式合并可以得到一个很不错的复杂度 不过利用线段树维护这个东西 在区间 ...

  2. AutoMapper 9.0的改造(续)

    上一篇有一个读者,有疑问,如何自动化注册Dto 我开篇,做了一个自动化注册的 public sealed class AutoInjectAttribute : Attribute { public ...

  3. 当asp.net core偶遇docker一(模型验证和Rabbitmq 一)

    比如我们有一些设计,依赖于某些软件,比如rabbitmq 当管理员功能,反复错误三五次之后,就发送一条消息到队列里去,我们又不希望对原先设计带来侵入式的改变业务 这个时候,我们就可以在模型验证里面加入 ...

  4. MySQL面试题!新鲜出炉~

    01.Mysql 的存储引擎,myisam和innodb的区别? 答:1.MyISAM 是非事务的存储引擎,适合用于频繁查询的应用.表锁,不会出现死锁,适合小数据,小并发. 2.innodb是支持事务 ...

  5. 最全总结!聊聊 Python 调用 JS 的几种方式

    1. 前言 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很多已经做案例的人,却不知道如何去学习更加高深的知识.那么针对这三类人,我给大 ...

  6. 搞大数据,Java 工程师需要掌握哪些知识?

    先看再点赞,给自己一点思考的时间,微信搜索[沉默王二]关注这个有颜值却假装靠才华苟且的程序员.本文 GitHub github.com/itwanger 已收录,里面还有一线大厂整理的面试题,以及我的 ...

  7. 蜻蜓点水说说Redis的ziplist的奥秘

    本篇博客参考: Redis 深度历险:核心原理与应用实践 Redis内部数据结构详解(4)--ziplist Redis的压缩列表ZipList 上篇博客中,我给大家蜻蜓点水般的介绍了Redis中SD ...

  8. 修改jar包配置文件的正确操作,jar包解压出来的文件夹重新打成jar,不依靠开发工具!!!!

    修改jar包配置文件的正确操作,有的时候通过一些解压工具可以对内部的文件进行修改,但是有时候会无效.这就很烦了 一.背景:       有一个springboot项目,事先我已经用编译好打成jar包以 ...

  9. Go 中的动态作用域变量

    这是一个 API 设计的思想实验,它从典型的 Go 单元测试惯用形式开始: func TestOpenFile(t *testing.T) { f, err := os.Open("notf ...

  10. 高级搜索树-红黑树(RBTree)解析

    目录 红黑树的定义 节点与树的定义 旋转操作 插入操作 情况1:p的兄弟u为黑色 情况2: p的兄弟u为红色 插入操作性能分析 代码实现 删除操作 情况1:x的接替者succ为红色 情况2:x的接替者 ...