当前位置:网站首页>JRS303-数据校验
JRS303-数据校验
2022-08-11 06:54:00 【花棉袄】
🧑 个人主页:花棉袄
本章内容:【JRS303-数据校验】
版权: 本文由【花棉袄】原创在CSDN首发需要转载请联系博主
如果文章对你有帮助【关注点赞️收藏】
JSR303介绍
- 在Java中提供了一系列的校验方式
- 这些校验方式在“javax.validation.constraints”包中
- 提供了如@Email,@NotNull等注解
1️⃣引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
- 在非空处理方式上提供了@NotNull,@NotBlank和@NotEmpty
2️⃣常用注解
- 所有校验注解都在:
javax.validation.constraints
包下
@NotNull
- 注解元素禁止为null,能够接收任何类型
@NotEmpty
- 该注解修饰的字段不能为null或""
- 支持以下几种类型
集合长度的计算
Map (map size is evaluated)
map长度的计算
Array (array length is evaluated)
数组长度的计算
@NotBlank
- 该注解不能为null,并且至少包含一个非空格字符
- 接收字符序列
3️⃣开启校验
@Valid
- controller中加校验注解@Valid,开启校验
🥌数据校验测试
- 步骤1:实体类字段上使用校验注解 @NotNull @NotEmpty @NotBlank @Pattern
- 步骤2:controller中加校验注解@Valid,开启校验
- 步骤3:给校验的Bean后,紧跟一个BindResult,就可以获取到校验的结果,拿到校验的结果,就可以自定义的封装
public R save(@Valid @RequestBody BrandEntity brand, BindingResult result){
}
- 实体中添加注解
@Data
public class Student {
@NotEmpty(message ="姓名不能为空")
private String name;
}
- controller层中保存方法添加:@Valid
@RestController
public class TestController {
@RequestMapping("/test")
public Result test(@Valid @RequestBody Student student, BindingResult result) {
String name = student.getName();
HashMap<String, Object> map = new HashMap<>();
map.put("name",name);
map.put("errors",result.getFieldErrors());
return Result.ok(map,"数据校验");
}
}
- ️ 测试:http://localhost:8080/test
{
"name":""
}
- ️ 返回信息
{
"code": 200,
"msg": "数据校验",
"data": {
"name": "",
"errors": [
{
"codes": [
"NotEmpty.student.name",
"NotEmpty.name",
"NotEmpty.java.lang.String",
"NotEmpty"
],
"arguments": [
{
"codes": [
"student.name",
"name"
],
"arguments": null,
"defaultMessage": "name",
"code": "name"
}
],
"defaultMessage": "姓名不能为空",
"objectName": "student",
"field": "name",
"rejectedValue": "",
"bindingFailure": false,
"code": "NotEmpty"
}
]
}
}
1️⃣自定义的封装错误信息
@RestController
public class TestController {
@RequestMapping("/test")
public Result test(@Valid @RequestBody Student student, BindingResult result) {
String name = student.getName();
Map<String, String> map = new HashMap<>();
map.put("name", name);
if (result.hasErrors()) {
//1.获取错误的校验结果
result.getFieldErrors().forEach((item) -> {
//2.获取发生错误时的message
String message = item.getDefaultMessage();
//3.获取发生错误的字段
String field = item.getField();
map.put(field, message);
});
return Result.fail(map, "数据校验");
} else {
return Result.ok(map);
}
}
}
- ️ 测试:http://localhost:8080/test
{
"name":""
}
- ️ 错误信息
{
"code": 500,
"msg": "数据校验",
"data": {
"name": "姓名不能为空"
}
}
2️⃣统一异常处理
- springmvc统一处理异常
@Slf4j
@RestControllerAdvice(basePackages = "com.michale.jrs303.controllers")
public class FireflyMallExceptionControllerAdvice {
/** * 处理数据校验问题 * @param e * @return */
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public Result handleVaildException(MethodArgumentNotValidException e) {
log.error("数据校验出现问题:{},异常类型:{}", e.getMessage(), e.getClass());
BindingResult bindingResult = e.getBindingResult();
Map<String, String> errorMap = new HashMap();
bindingResult.getFieldErrors().forEach((fieldError) -> {
errorMap.put(fieldError.getField(), fieldError.getDefaultMessage());
});
return Result.fail(errorMap, "数据校验出现问题");
}
/** * 处理其他异常 * @param throwable * @return */
@ExceptionHandler(value = Throwable.class)
public Result handleException(Throwable throwable) {
return Result.fail();
}
}
@RequestMapping("/testException")
public Result testException(@Valid @RequestBody Student student) {
String name = student.getName();
Map<String, String> map = new HashMap<>();
map.put("name", name);
return Result.ok(map);
}
- ️ 测试统一异常处理:测试:http://localhost:8080/testException
{
"name":"",
}
- ️ 错误信息
{
"code": 500,
"msg": "数据校验出现问题",
"data": {
"name": "姓名不能为空"
}
}
JSR303分组校验
1️⃣创建分组校验接口
/** * @Author 天才小狐狸 * @Data 2022/8/11 2:03 * @Description 姓名校验分组 */
public interface NameGroup {
}
/** * @Author 天才小狐狸 * @Data 2022/8/11 2:04 * @Description 年龄校验分组 */
public interface AgeGroup {
}
2️⃣添加校验注解
@Data
public class Student {
@NotEmpty(message ="姓名不能为空",groups = NameGroup.class)
private String name;
@NotEmpty(message ="绰号不能为空",groups = NameGroup.class)
private String nickName;
@Min(value = 18,message = "年龄下限不能低于18岁" ,groups = AgeGroup.class)
private String age;
@Max(value = 60,message = "年龄上限不能超过60岁" ,groups = AgeGroup.class)
private String retireAge;
}
3️⃣开启分组校验
- @Validated(NameGroup.class)指定校验分组
@RequestMapping("/testGroup")
public Result testGroup(@Validated(NameGroup.class) @RequestBody Student student) {
String name = student.getName();
String nickName = student.getNickName();
String age = student.getAge();
String retireAge = student.getRetireAge();
Map<String, String> map = new HashMap<>();
map.put("name", name);
map.put("nickname", nickName);
map.put("age", age);
map.put("retireAge", retireAge);
return Result.ok(map);
}
- ️ 测试分组校验:http://localhost:8080/testGroup
{
"name":"",
"nickName":"",
"age":"17",
"retireAge":"66"
}
- ️ 错误信息
{
"code": 500,
"msg": "数据校验出现问题",
"data": {
"nickName": "绰号不能为空",
"name": "姓名不能为空"
}
}
- @Validated(AgeGroup.class)指定校验分组
@RequestMapping("/testGroup")
public Result testGroup(@Validated(AgeGroup.class) @RequestBody Student student) {
String name = student.getName();
String nickName = student.getNickName();
String age = student.getAge();
String retireAge = student.getRetireAge();
Map<String, String> map = new HashMap<>();
map.put("name", name);
map.put("nickname", nickName);
map.put("age", age);
map.put("retireAge", retireAge);
return Result.ok(map);
}
- ️ 测试分组校验:http://localhost:8080/testGroup
{
"name":"",
"nickName":"",
"age":"17",
"retireAge":66
}
- ️ 错误信息
{
"code": 500,
"msg": "数据校验出现问题",
"data": {
"retireAge": "年龄上限不能超过60岁",
"age": "年龄下限不能低于18岁"
}
}
JSR303自定义校验
1️⃣编写自定义的校验注解
- 比如要创建一个:@ListValue 注解,被标注的字段值只能是:0或1
@Documented
@Target({
METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
public @interface ListValue {
// 使用该属性去Validation.properties中取
String message() default "{com.atguigu.common.valid.ListValue.message}";
Class<?>[] groups() default {
};
Class<? extends Payload>[] payload() default {
};
int[] value() default {
};
}
- 设置错误信息:创建文件ValidationMessages.properties
com.firefly.common.valid.ListValue.message=必须提交指定的值 [0,1]
2️⃣编写自定义的校验器
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.HashSet;
import java.util.Set;
/** * @author Michale @EMail:[email protected] * @Date: 2022/1/8 19:23 * @Name ListValueConstraintValidator * @Description: */
public class ListValueConstraintValidator implements ConstraintValidator<ListValue, Integer> {
private Set<Integer> set = new HashSet<>();
@Override
public void initialize(ListValue constraintAnnotation) {
//获取注解允许的值
int[] value = constraintAnnotation.value();
for (int i : value) {
set.add(i);
}
}
@Override
public boolean isValid(Integer value, ConstraintValidatorContext context) {
//判断传入的值是否在满足允许的值
boolean b = set.contains(value);
return b;
}
}
3️⃣关联校验器和校验注解
- 在@ListValue注解关联校验器
@Constraint(validatedBy = {
ListValueConstraintValidator.class})
一个校验注解可以匹配多个校验器
4️⃣添加自定义的校验注解
@ListValue(value = {
0,1},groups = {
AgeGroup.class,MyJRS303Group.class})
private Integer gender;
- ️ 测试自定义校验器:http://localhost:8080/testGroup
{
"gender":"3"
}
{
"code": 500,
"msg": "数据校验出现问题",
"data": {
"gender": "必须提交指定的值 [0,1]"
}
}
边栏推荐
猜你喜欢
1036 跟奥巴马一起编程 (15 分)
1002 写出这个数 (20 分)
6月各手机银行活跃用户较快增长,创半年新高
Taobao product details API interface
技术分享 | 实战演练接口自动化如何处理 Form 请求?
【LaTex-错误和异常】\verb ended by end of line.原因是因为闭合边界符没有在\verb命令所属行中出现;\verb命令的正确和错误用法、verbatim环境的用法
1101 How many times B is A (15 points)
TF中的四则运算
TF通过feature与label生成(特征,标签)集合,tf.data.Dataset.from_tensor_slices
数仓开发知识总结
随机推荐
无服务器+域名也能搭建个人博客?真的,而且很快
1076 Wifi密码 (15 分)
Waldom Electronics宣布成立顾问委员会
Redis source code-String: Redis String command, Redis String storage principle, three encoding types of Redis string, Redis String SDS source code analysis, Redis String application scenarios
1056 组合数的和 (15 分)
梅科尔工作室——BP神经网络
Pico neo3在Unity中的交互操作
【软件测试】(北京)字节跳动科技有限公司终面HR面试题
基于FPGA的FIR滤波器的实现(5)— 并行结构FIR滤波器的FPGA代码实现
1081 检查密码 (15 分)
1003 我要通过 (20 分)
MindManager2022全新正式免费思维导图更新
Unity开发者必备的C#脚本技巧
Tensorflow中使用tf.argmax返回张量沿指定维度最大值的索引
Activity的四种启动模式
DDR4内存条电路设计
Item 2 - Annual Income Judgment
[Recommender System]: Overview of Collaborative Filtering and Content-Based Filtering
如何选择专业、安全、高性能的远程控制软件
tf.reduce_mean()与tf.reduce_sum()