【开发日记】SpringBoot做参数校验
目录:
1、前言 2、加入依赖 3、创建VO实体类 4、创建接口 5、创建全局异常处理器 6、添加效验注解 7、分组 8、优化参数效验 9、@Validated或@Valid区别 10、效果
1、前言
这里的参数效验指的是在Web接口中接收参数时对参数的合法性进行效验;正常情况的做法是在接收到参数时,在方法体中对参数进行核验;这样做的代码整洁性太差、代码侵入性太强;这里推荐一个利用SpringBoot
中推荐的注解方式进行参数效验。
2、加入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
3、创建VO实体类
@Data
public class Parameter implements Serializable {
String scene;
ArrayList<Point> path;
Double speed;
Integer state;
JSONObject inputValues;
}
这个类用于接收客户端的请求参数;使用实体类接收参数时实体类需要有Getter、Setter方法,我这里用到Lombok
下的@Data
注解自动生成这些方法,所以就没有加Getter、Setter方法。
4、创建接口
@PostMapping("")
public RequestResult app(@Validated @RequestBody Parameter parameter) {
RequestResult requestResult = new RequestResult();
requestResult.appendData("result", app.start(parameter));
return requestResult;
}
需要在接收参数的实体类上加入@Validated
或@Valid
注解,否则参数效验不会生效,这两个注解的区别后面说明。
相信能看到这里的小伙伴使用SpringMVC
创建接口应该问题不大,所以这里就不展示接口类了,重点在使用实体类接收参数时如何使用注解对参数进行效验。
5、创建全局异常处理器
@RestControllerAdvice
public class ParameterExceptionHandler {
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public RequestResult handleMethodArgumentNotValidException(MethodArgumentNotValidException e, HttpServletRequest request) {
RequestResult requestResult = new RequestResult();
requestResult.setCode(400);
requestResult.setMessage(Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage());
requestResult.appendData("url",request.getRequestURI());
return requestResult;
}
}
当参数效验失败,会抛出MethodArgumentNotValidException
异常,这个类的作用就是捕获这个异常,然后将这个异常翻译成用户能看懂的样子。
6、添加效验注解
用于效验的注解可用于方法参数中,也可以用于实体类中;如果是实体类中使用的话,需要在方法参数实体类前加入@Validated
注解;如果实体类中有嵌套其他的实体类,也需要参数效验,则使用@Valid
注解标识,@Validated
或@Valid
注解区别会在后面说明。
①@NotEmpty
表示不能为null
,也不能为空字符串,当类型为集合时集合不能为空,但是字符串可以是" "
(注意引号之间有一个空格)。
@NotEmpty(message = "季节不能为空")
String scene;
②@NotNull
表示不可以为null
,但可以是空字符串;
@NotNull(message = "季节不能为空")
String scene;
③@NotBlank
用于字符串,表示不能为null,也不能为空字符串,空格字符串也不行。
④@Length
用于字符串上,限制字符串长度。
@Length(max = 1,min = 1,message = "用于表示季节的字符为A(夏季)、B(冬季)")
String scene;
⑤@Size
用于字符串、数组和集合上,也是限制长度。
@Size(min = 2, message = "表示路线的坐标点应该不少于2个")
ArrayList<Point> path;
⑥@Min
和@Max
表示最小值和最大值,用于字符串或数值上,如果是字符串则转换为BigDecimal
再进行比较。
@Min(value = 10,message = "速度应大于等于10千米每小时")
@Max(value = 20,message = "速度应小于等于20千米每小时")
Double speed;
⑦@Range
表示取值范围,与@Min
和@Max
组合使用类似。
@Range(min = 1, max = 3, message = "状态应使用1-正常、2-加速、3-慢速")
Integer state;
⑧@Email
效验邮箱格式。
@Email(message = "格式不符合规范")
String mail;
⑨@URL
表示该参数值必须是一个URL。
@URL(message = "格式不符合规范")
String url;
⑩@Pattern
表示该参数值必须符合这个正则表达式。
@Pattern(regexp = "^[A-Z]+$",message = "格式不符合规范")
String scene;
7、分组
使用@Validated
注解可设置参数效验分组;示例如下:
① 创建两个分组
public interface Autumn {
}
public interface Spring {
}
② 控制器接口
表示当前是Spring
分组;
@PostMapping("")
public RequestResult app(@Validated({Spring.class}) @RequestBody Parameter parameter) {
RequestResult requestResult = new RequestResult();
requestResult.appendData("result", app.start(parameter));
return requestResult;
}
③标识参数分组
表示只有当前分组是Autumn
时才会生效。
@Size(min = 2, message = "表示路线的坐标点应该不少于2个",groups = {Autumn.class})
ArrayList<Point> path;
8、优化参数效验
如上的效验过程中,会效验所有的参数,然后把不合格的全部返回给客户端。
通过如下配置可以做到当有一个参数效验不通过时即返回,不用效验所有参数,增加效率。
@Configuration
public class AppConfig {
@Bean
public Validator validator(AutowireCapableBeanFactory beanFactory) {
try (ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
.configure().failFast(true)
.constraintValidatorFactory(new SpringConstraintValidatorFactory(beanFactory))
.buildValidatorFactory()) {
return validatorFactory.getValidator();
}
}
}
9、@Validated
或@Valid
区别
①用法
@Validated
注解可被用于方法、参数上;无法用于成员属性上;
@Valid
注解可被用于方法、构造方法、参数和成员属性上;
②分组
@Validated
注解提供分组用法,可根据分组情况提供不同的参数效验规则;
@Valid
注解不提供;
10、效果
参数效验未通过后的效果如下:
{
"code": 400,
"message": "表示路线的坐标点应该不少于2个",
"data": {
"url": "/test"
}
}
相关文章
- Java项目毕业设计:基于springboot+vue的电影视频网站系统「建议收藏」
- springboot到底是什么_Springboot启动流程
- SpringBoot框架_skynet框架详解
- SpringBoot的启动流程_springboot启动卡住了
- 基于SpringBoot的JWT单点登录
- SpringBoot面试题及答案整理
- 写给Java开发看的 Docker 干货(零基础部署Nginx MySQL SpringBoot)
- 解决springboot 2.0集成elasticsearch 7.6.2 查询总数为10000
- springboot mysql事物_SpringBoot事务详细简介[通俗易懂]
- springBoot跨域注解@CrossOrigin
- [入门]SpringBoot-MyBatis-luckwheel-master开源代码审计
- SpringBoot(九) - Swagger
- 4-基于SpringBoot的Web开发
- 10年开发大牛教你如何学习获取调试SpringBoot源代码
- SpringBoot消息源码解析:JMS基础自动配置
- SpringBoot打包:Failed to execute goal org.apache.maven.plugins
- Vue上传文件到springboot
- springboot validated注解数据校验 异常处理
- SpringBoot简介
- [Springboot]JPA和MyBatis性能对比
- SpringBoot事件监听机制及观察者/发布订阅模式详解
- 数据库开发知识:SpringBoot 怎么集成MongoDB实现文件上传功能
- springboot-security02FromDB 权限管理(用户信息和角色信息保存在数据库)详解程序员
- SpringBoot(二)Web整合开发详解编程语言
- SpringBoot集成Quartz实现定时器详解编程语言
- Springboot后端接口开发-文件上传接口详解编程语言