曾经参数的验证是这样的:

    public String test(User user){
if(user == null){
throw new NullPointerException("user 不能为空");
} if(user.getUserName() == null){
throw new NullPointerException("userName 不能为空");
} if(user.getUserName().length() < 4 || user.getUserName().length()>10){
throw new RuntimeException("userName 长度小于4位或大于10位");
} return "success";
}

随着参数的增加,格式的变化,校验数据有效性的代码愈发繁琐。

通过Spring boot来完成参数数据校验。

JSR-303注解介绍

这里只列举了javax.validation包下的注解,同理在spring-boot-starter-web包种也存在hibernate-validator验证包,里面包含了一些javax.validation没有的注解。

注解 说明
@NotNull 限制必须不为null
@NotEmpty 验证注解的元素值不为 null 且不为空(字符串长度不为0、集合大小不为0)
@NotBlank 验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格
@Pattern(value) 限制必须符合指定的正则表达式
@Size(max,min) 限制字符长度必须在 min 到 max 之间(也可以用在集合上)
@Email 验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式
@Max(value) 限制必须为一个不大于指定值的数字
@Min(value) 限制必须为一个不小于指定值的数字
@DecimalMax(value) 限制必须为一个不大于指定值的数字
@DecimalMin(value) 限制必须为一个不小于指定值的数字
@Null 限制只能为null(很少用)
@AssertFalse 限制必须为false (很少用)
@AssertTrue 限制必须为true (很少用)
@Past 限制必须是一个过去的日期
@Future 限制必须是一个将来的日期
@Digits(integer,fraction) 限制必须为一个小数,且整数部分的位数不能超过 integer,小数部分的位数不能超过 fraction (很少用)

实体类

public class Book implements Serializable {

    private Integer id;

    @NotBlank(message = "name 不能为空")
@Length(min = 2, max = 10, message = "name 长度必须在{min}-{max}之间")
private String name; @NotNull(message = "price 不能为空")
@DecimalMin(value = "0.1", message = "价格不能低于 {value}")
private BigDecimal price; ...
}

控制层

这些验证注解不仅仅可以放在controller上,也可以加在service层上。

//todo 开启数据有效性校验,添加在类上即为验证方法,添加在方法参数中即为验证参数对象。(添加在方法上无效)
@Validated
@RequestMapping("/books")
@RestController
public class BookController { @GetMapping("/test1")
public String test1(@NotBlank(message = "name不能为空") @Length(min = 2, max = 10 , message="name 长度必须在{min}-{max}之间") String name){
return "test1";
} @GetMapping("test2")
public String test2(@Validated Book book){
return "test2";
}
}

这样就可以了,在浏览器中输入 /books/test1/ 不输入参数会抛异常 /books/test1?name=sdf 则可以通过验证

/books/test2/ 异常 /books/test2?name=sdf&price=0.5就ok了

Spring Boot 还允许我们自定义Validatior

自定义注解

package com.spring.boot.utils;

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; //@Target定义范围 在字段 参数上使用
@Target({ElementType.FIELD, ElementType.PARAMETER})
//定义可见范围 RUNTIME整个运行阶段都可见
@Retention(RetentionPolicy.RUNTIME)
//Constraint指定具体校验器类
@Constraint(validatedBy = DateTimeValidator.class)
//@interface 定义注解
public @interface DateTime {
String message() default "格式错误"; String format() default "yyyy-MM-dd"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {};
}

具体的校验器

package com.spring.boot.utils;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.text.ParseException;
import java.text.SimpleDateFormat; /**
* 日期格式验证
*/
public class DateTimeValidator implements ConstraintValidator<DateTime, String> { private DateTime dateTime; @Override
//初始化,它可以获得当前注解的所有属性
public void initialize(DateTime constraintAnnotation) {
this.dateTime = constraintAnnotation;
} @Override
//约束验证的主体方法,其中s就是验证参数的具体事例,context代表约束执行的上下文
public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
//如果为空不用验证, 为空验证可以用@NotBlank、@NotNull等参数进行控制
if (s == null) {
return true;
} String format = dateTime.format();
if (s.length() != format.length()) {
return false;
} SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
try {
simpleDateFormat.parse(s);
} catch (ParseException e) {
return false;
}
return true;
}
}

然后在控制层使用他

    @GetMapping("/test3")
public String test3(@NotBlank(message = "date 不能为空") @DateTime(message = "您如的格式错误,正确的格式为:{format}",format = "yyyy-MM-dd HH:mm") String date){
return "test3";
}

测试

分组验证

  有时候我们需要对一个实体类有多种验证方式,在不同的情况下使用不同的验证方式,比如id,新增的时候是不需要的,更新时是必须的。

定义一个验证组,里面写上不同的空接口类即可

public class Groups {
public interface Update{ } public interface Default{ }
}

实体类

  groups属性的作用就让@Validated注解只验证与自身value属性想匹配的字段,可多个,只要满足就会去纳入验证范围。

public class Book {

    @NotNull(message = "id 不能为空" , groups = Groups.Update.class)
private Integer id; @NotBlank(message = "name 不能为空" , groups = Groups.Default.class)
private String name; @NotNull(message = "price 不能为空" , groups = Groups.Default.class)
private BigDecimal price;

控制层

  创建一个ValidateControoler类,然后定义好insert、update两个方法,由于insert方法并不关心id字段,所以这里的@Validate的value属性写成Groups.Default.class就可以了,而update方法需要Id,所以此处@Validated注解的value属性值就要写成Groups.Default.class,Groups.Update.Class。代表只要是这分组下的数据都需要进行数据有效性校验操作

@RestController
public class ValidateController {
//default中没有id
@GetMapping("/insert")
public String insert(@Validated(value=Groups.Default.class) Book book){
return "insert";
} //update中有id校验
@GetMapping("update")
public String update(@Validated(value={Groups.Default.class,Groups.Update.class}) Book book){
return "update";
} }

Spring Boot (31) 数据验证的更多相关文章

  1. Spring Boot的数据访问:CrudRepository接口的使用

    示例 使用CrudRepository接口访问数据 创建一个新的Maven项目,命名为crudrepositorytest.按照Maven项目的规范,在src/main/下新建一个名为resource ...

  2. Kotlin + Spring Boot 请求参数验证

    编写 Web 应用程序的时候,经常要做的事就是要对前端传回的数据进行简单的验证,比如是否非空.字符长度是否满足要求,邮箱格式是否正确等等.在 Spring Boot 中,可以使用 Bean Valid ...

  3. spring boot+jwt 权限验证

    上周看了一下jwt以前公司的开发都是使用session共享的方法.现在主流的两种方式一种是把登录信息保存在服务器,另一种则是把信息保存在客户端.在使用session 存储的时候会遇到很多的问题,随着项 ...

  4. Spring Boot的数据访问 之Spring Boot + jpa的demo

    1. 快速地创建一个项目,pom中选择如下 <?xml version="1.0" encoding="UTF-8"?> <project x ...

  5. Spring Boot与数据

    SpringBoot 着眼于JavaEE! 不仅仅局限于 Mybatis .JDBC. Spring Data JPA Spring Data 项目的目的是为了简化构建基于 Spring 框架应用的数 ...

  6. Spring Boot 高效数据聚合之道

    项目地址和示例代码: https://github.com/lvyahui8/spring-boot-data-aggregator 背景 接口开发是后端开发中最常见的场景, 可能是RESTFul接口 ...

  7. (8)Spring Boot 与数据访问

    文章目录 简介 整合基本的JDBC与数据源 整合 druid 数据源 整合 mybatis 简介 对于数据访问层,无论是 SQL 还是 NOSQL ,Spring Boot 默认都采用整合 Sprin ...

  8. Spring Boot框架 - 数据访问 - 整合Mybatis

    一.新建Spring Boot项目 注意:创建的时候勾选Mybatis依赖,pom文件如下 <dependency> <groupId>org.mybatis.spring.b ...

  9. Spring Boot实现数据访问计数器

    1.数据访问计数器   在Spring Boot项目中,有时需要数据访问计数器.大致有下列三种情形: 1)纯计数:如登录的密码错误计数,超过门限N次,则表示计数器满,此时可进行下一步处理,如锁定该账户 ...

随机推荐

  1. [bzoj4826][Hnoi2017]影魔_单调栈_主席树

    影魔 bzoj-4826 Hnoi-2017 题目大意:给定一个$n$个数的序列$a$,求满足一下情况的点对个数: 注释:$1\le n,m\le 2\cdot 10^5$,$1\le p1,p2\l ...

  2. mysql 安装与卸载

    mysql用了也好几年了,但每次安装完或者卸载完就忘记了安装步骤以及卸载步骤,因此将关键的步骤记录下来,供以后参考. 1.mysql安装 ①安装类型有typical,complete,custom,一 ...

  3. 学习日常笔记<day09>Http协议

    1 Http协议入门 1.1 什么是http协议 http协议: 对浏览器客户端 和  服务器端 之间数据传输的格式规范 1.2 查看http协议的工具 1)使用火狐的firebug插件(右键-> ...

  4. Redis Cluster集群搭建后,客户端的连接研究(Spring/Jedis)(待实践)

    说明:无论是否已经搭建好集群,还是使用什么样的客户端去连接,都是必须把全部IP列表集成进去,然后随机往其中一个IP写. 这样做的好处: 1.随机IP写入之后,Redis Cluster代理层会自动根据 ...

  5. springboot整体介绍

    1.springboot:快速开发,强大的运维能力.(监控,服务发现,并打) 2.微服务,将一个大系统分解成很多独立的小服务,这些服务能随时发布. 3.2004年第一版spring 1.0,rod j ...

  6. TCP打洞与UDP打洞的差别

    为什么网上讲到的P2P打洞基本上都是基于UDP协议的打洞?难道TCP不可能打洞?还是TCP打洞难于实现?     如果如今有内网clientA和内网clientB.有公网服务端S.     如果A和B ...

  7. CentOS 7加强安全性:

    CentOS 7加强安全性:1. 更改 root 密码************************************************************************* ...

  8. 在DevExpress GridControl的一列中显示图片

    作者:jiankunking 出处:http://blog.csdn.net/jiankunking 近期做项目的时候用到了将GridControl中一列设置为PictureEdit类型,然后通过这一 ...

  9. UML——用例图

    用例图是在需求分析阶段开发人员和用户对需求规格达成的某种共识.它描写叙述了待开发系统的功能需求. UML视频使我们对用例图的基本组成元素.属性.粒度等有了理论上的理解,我们还须要自己亲自己主动手画一画 ...

  10. C#编译器优化那点事 c# 如果一个对象的值为null,那么它调用扩展方法时为甚么不报错 webAPI 控制器(Controller)太多怎么办? .NET MVC项目设置包含Areas中的页面为默认启动页 (五)Net Core使用静态文件 学习ASP.NET Core Razor 编程系列八——并发处理

    C#编译器优化那点事   使用C#编写程序,给最终用户的程序,是需要使用release配置的,而release配置和debug配置,有一个关键区别,就是release的编译器优化默认是启用的.优化代码 ...