有参数传递的地方都少不了参数校验。在web开发中,前端的参数校验是为了用户体验,后端的参数校验是为了安全。试想一下,如果在controller层中没有经过任何校验的参数通过service层、dao层一路来到了数据库就可能导致严重的后果,最好的结果是查不出数据,严重一点就是报错,如果这些没有被校验的参数中包含了恶意代码,那就可能导致更严重的后果。
实践
一、引入依赖
<!--引入spring-boot-starter-validation--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
二、使用校验
在controller层的参数校验可以分为两种场景:
单个参数校验
实体类参数校验
2.1 单参数校验
/** * 参数校验测试 控制类 * @author oyc */ @RestController @RequestMapping("user") @Validated public class RequestParamsValidatedController { private Logger logger = LoggerFactory.getLogger(this.getClass()); @GetMapping public User test(@NotNull(message = "姓名不能为空") String name, @NotNull(message = "年龄不能为空") @Max(value = 99, message = "不能大于200岁") Integer age) { logger.info("name:" + name + " -age:" + age); return new User(name, age); } }
2.2 实体类参数校验
/** * 参数校验测试 控制类 * @author oyc */ @RestController @RequestMapping("user") @Validated public class RequestParamsValidatedController { private Logger logger = LoggerFactory.getLogger(this.getClass()); @PostMapping public User save(@Validated User user) { logger.info(user.toString()); return user; } }
package com.oycbest.springbootvalidated.vo; import javax.validation.constraints.*; import java.io.Serializable; /** * 用户实体类 * @author oyc */ public class User implements Serializable { private String userId; @NotNull(message = "用户名不能为空") private String userName; @NotNull(message = "年龄不能为空") @Max(value = 100, message = "年龄不能大于100岁") private int age; @NotNull(message = "邮箱不能为空") @Email(message = "邮箱格式不正确") private String email; @NotNull(message = "电话号码不能为空") private String phoneNumber; public User(@NotNull(message = "用户名不能为空") String userName, int age) { this.userName = userName; this.age = age; } public User() { } public User(String userId, @NotNull(message = "用户名不能为空") String userName, int age, String email, String phoneNumber) { this.userId = userId; this.userName = userName; this.age = age; this.email = email; this.phoneNumber = phoneNumber; } public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getPhoneNumber() { return phoneNumber; } public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; } @Override public String toString() { return "User{" + "userId='" + userId + '\'' + ", userName='" + userName + '\'' + ", age=" + age + ", email='" + email + '\'' + ", phoneNumber='" + phoneNumber + '\'' + '}'; } }
2.3 定义统一异常处理
package com.oycbest.springbootvalidated.exception; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Bean; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import org.springframework.validation.BindException; import org.springframework.validation.FieldError; import org.springframework.validation.beanvalidation.MethodValidationPostProcessor; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; import javax.validation.ValidationException; import java.util.List; import java.util.Set; /** * 全局异常处理 * * @author oyc */ @ControllerAdvice @Component public class GlobalExceptionHandler { private Logger logger = LoggerFactory.getLogger(this.getClass()); @Bean public MethodValidationPostProcessor methodValidationPostProcessor() { return new MethodValidationPostProcessor(); } @ExceptionHandler @ResponseBody @ResponseStatus(HttpStatus.BAD_REQUEST) public String handle(ValidationException exception) { logger.error("请求异常:" + exception.getMessage()); if (exception instanceof ConstraintViolationException) { ConstraintViolationException exs = (ConstraintViolationException) exception; Set<ConstraintViolation<?>> violations = exs.getConstraintViolations(); for (ConstraintViolation<?> item : violations) { //打印验证不通过的信息 logger.error("请求异常:" + item.getMessage()); } } return "请求异常: " + exception.getMessage(); } @ResponseBody @ExceptionHandler(value = BindException.class) public String bindException(Exception e) { if (e instanceof BindException) { BindException exs = (BindException) e; List<FieldError> fieldErrors = exs.getFieldErrors(); for (FieldError item : fieldErrors) { logger.error("请求异常:" + item.getDefaultMessage()); } } logger.error("数据绑定异常:" + e.getMessage()); return "数据绑定异常"; } @ResponseBody @ExceptionHandler(value = Exception.class) public String defaultException(Exception e) { logger.error("请求异常:" + e.getMessage()); return "请求异常 " + e.getMessage(); } }
三、约束性注解(简单)说明
注解 |
功能 |
@AssertFalse |
可以为null,如果不为null的话必须为false |
@AssertTrue |
可以为null,如果不为null的话必须为true |
@DecimalMax |
设置不能超过最大值 |
@DecimalMin |
设置不能超过最小值 |
@Digits |
设置必须是数字且数字整数的位数和小数的位数必须在指定范围内 |
@Future |
日期必须在当前日期的未来 |
@Past |
日期必须在当前日期的过去 |
@Max |
最大不得超过此最大值 |
@Min |
最大不得小于此最小值 |
@NotNull |
不能为null,可以是空 |
@Null |
必须为null |
@Pattern |
必须满足指定的正则表达式 |
@Size |
集合、数组、map等的size()值必须在指定范围内 |
|
必须是email格式 |
@Length |
长度必须在指定范围内 |
@NotBlank |
字符串不能为null,字符串trim()后也不能等于“” |
@NotEmpty |
不能为null,集合、数组、map等size()不能为0;字符串trim()后可以等于“” |
@Range |
值必须在指定范围内 |
@URL |
必须是一个URL |
到此这篇关于SpringBoot + validation 接口参数校验的文章就介绍到这了,更多相关SpringBoot + validation 接口参数校验内容请搜索小牛知识库以前的文章或继续浏览下面的相关文章希望大家以后多多支持小牛知识库!
本文向大家介绍SpringBoot使用validation-api实现参数校验的示例,包括了SpringBoot使用validation-api实现参数校验的示例的使用技巧和注意事项,需要的朋友参考一下 我们在开发Java项目的时候,经常需要对参数进行一些必填项、格式、长度等进行校验,如果手写代码对参数校验,每个接口会需要很多低级的代码,这样会降低代码的可读性。那么我们能不能使用一种比较优雅的方式
本文向大家介绍SpringBoot实现短信验证码校验方法思路详解,包括了SpringBoot实现短信验证码校验方法思路详解的使用技巧和注意事项,需要的朋友参考一下 有关阿里云通信短信服务验证码的发送,请参考我的另一篇文章 Springboot实现阿里云通信短信服务有关短信验证码的发送功能 思路 用户输入手机号后,点击按钮获取验证码。并设置冷却时间,防止用户频繁点击。 后台生成验证码并发送到用户
本文向大家介绍springboot使用校验框架validation校验的示例,包括了springboot使用校验框架validation校验的示例的使用技巧和注意事项,需要的朋友参考一下 b/s系统中对http请求数据的校验多数在客户端进行,这也是出于简单及用户体验性上考虑,但是在一些安全性要求高的系统中服务端校验是不可缺少的。 Spring3支持JSR-303验证框架,JSR-303 是Java
业务参数校验采用JSR-303方式,关于JSR-303介绍可以参考这篇博文:JSR 303 - Bean Validation 介绍及最佳实践 在参数中使用注解即可,框架会自动进行验证。如下面一个添加商品接口,它的参数是GoodsParam @Api(name = "goods.add") public void addGoods(GoodsParam param) { ... } 在G
业务参数校验采用JSR-303方式,关于JSR-303介绍可以参考这篇博文:JSR 303 - Bean Validation 介绍及最佳实践 在参数中使用注解即可,框架会自动进行验证。如下面一个添加商品接口,它的参数是GoodsParam @Open("goods.add") @RequestMapping("/goods/add") public void addGoods(GoodsPara
本文向大家介绍详解Vue中Axios封装API接口的思路及方法,包括了详解Vue中Axios封装API接口的思路及方法的使用技巧和注意事项,需要的朋友参考一下 一、axios的封装 在vue项目中,和后台交互获取数据这块,我们通常使用的是axios库,它是基于promise的http库,可运行在浏览器端和node.js中。他有很多优秀的特性,例如拦截请求和响应、取消请求、转换json、客户端防御X
本文向大家介绍Hibernate Validation自定义注解校验的实现,包括了Hibernate Validation自定义注解校验的实现的使用技巧和注意事项,需要的朋友参考一下 情景:需要对String类型的属性比如description进行验证,验证规则是当description为空时不进行正则校验,description不为空时进行正则校验。上述需求Hibernate Validatio
本文向大家介绍详解iOS 验证码输入的实现思路,包括了详解iOS 验证码输入的实现思路的使用技巧和注意事项,需要的朋友参考一下 如图所示,现在很多App采用了类似下划线、方块等方式的验证码输入,直观美观!对于这种效果的实现方式,大概有以下几种方式: 1.多个UITextField组成 这种方式好处是有光标闪烁、但是在处理删除和动画效果时,就会显得有点笨拙,OFO应该是这样实现的,要严格处理好每个U