参数校验机制

JSR-303 Hibernate

参数接收方式:

  • URL路径中的参数 {id} (@PathVariable(name="id") int-whatever)
  • URL中的查询参数 ?name=Chanuncy (@RequestPara(name String-whatever)
  • requestbody中的json字符串 {"name":"7yue","age":18} (@RequestBody Map<String,Object> person)
  • 一般会新建一个dto(data transfer object) 来接受和发送参数,一个对象一个dto
@Getter
@Builder
public class PersonDTO {
private String name;
private Integer age;
private String password1;
private String password2; }

简单参数检验:

@Validated 开启验证

@Range @Max @Min

@RestController
@RequestMapping("/banner")
//开启验证 下文@Max验证
@Validated
public class BannerController {
@RequestMapping("/test1/{id}")
public String test1(@PathVariable @Max(5) int id,
@RequestBody @Validated PersonDTO person){
//开启PersonDTO @Length验证
return "ok";
}

复杂参数验证:(对象)

@Validated 开启验证

@Valid 级联验证

PersonDTO:

@Getter
@Builder
//自定义注解后面会讲到
@PasswordEqual
public class PersonDTO {
@Length(min = 2, max=10, message = "大小不匹配")
private String name;
private Integer age; private String password1;
private String password2;
//@Valid 开启SchoolDTO schoolName 验证
private SchoolDTO school;
}
@Getter
@Setter
public class SchoolDTO{
@Length(min=2)
priavte String schoolName;
}

自定义参数校验注解:

当逻辑十分复杂时就要自己定义参数校验注解

先导:注解和反射

四个元注解:

  • @Target
  • @Rentention
  • @Documented
  • @Inherited

使用注解的机制:反射

通过反射获取Class实例的方法:

  • 对象.getClass()
  • 类.class
  • Class.forName(全类名)

新建一个验证两次输入相同字符串的注解

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
//将注解和逻辑处理类关联
@Constraint(validatedBy = PasswordValidator.class)
public @interface PasswordEqual {
String message() default "passwords are not equal"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {};
}

逻辑处理:

//ConstraintValidator<注解的名字,注解修饰的对象>
public class PasswordValidator implements ConstraintValidator<PasswordEqual, PersonDTO> {
@Override
public boolean isValid(PersonDTO personDTO, ConstraintValidatorContext constraintValidatorContext) {
String password1 = personDTO.getPassword1();
String password2 = personDTO.getPassword2();
boolean match = password1.equals(password2);
return match;
}
}

上述参数校验会抛出一个未处理的异常,所以我们要写对应的异常处理

在Spring-Boot异常处理(一)中的GlobalExceptionAdvice中添加:

//dto参数校验异常
@ResponseBody
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public UnifyResponse handleBeanValidation(HttpServletRequest req,MethodArgumentNotValidException e){
List<ObjectError> allErrors = e.getBindingResult().getAllErrors();
String errorMessage = this.formatAllErrorMessages(allErrors);
return new UnifyResponse(10001,errorMessage,req.getMethod() + ' ' + req.getRequestURI());
} //url参数异常
@ExceptionHandler(ConstraintViolationException.class)
@ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST)
public UnifyResponse handleConstraintViolationException(HttpServletRequest req, ConstraintViolationException e){
return new UnifyResponse(10001,e.getMessage(),req.getMethod() + ' ' + req.getRequestURI());
} //格式化dto参数校验异常错误信息
private String formatAllErrorMessages(List<ObjectError> errors){
StringBuffer errorMsg = new StringBuffer();
errors.forEach(error -> errorMsg.append(error.getDefaultMessage()).append(';'));
return errorMsg.toString();
}

SpringBoot异常处理(二)的更多相关文章

  1. C++中的异常处理(二)

    C++中的异常处理(二) 标签: c++C++异常处理 2012-11-24 20:56 1713人阅读 评论(2) 收藏 举报  分类: C++编程语言(24)  版权声明:本文为博主原创文章,未经 ...

  2. SpringBoot异常处理统一封装我来做-使用篇

    SpringBoot异常处理统一封装我来做-使用篇 简介 重复功能我来写.在 SpringBoot 项目里都有全局异常处理以及返回包装等,返回前端是带上succ.code.msg.data等字段.单个 ...

  3. Springboot异常处理和自定义错误页面

    1.异常来源 要处理程序发生的异常,首先需要知道异常来自哪里? 1.前端错误的的请求路径,会使得程序发生4xx错误,最常见的就是404,Springboot默认当发生这种错误的请求路径,pc端响应的页 ...

  4. SpringBoot开发二十-Redis入门以及Spring整合Redis

    安装 Redis,熟悉 Redis 的命令以及整合Redis,在Spring 中使用Redis. 代码实现 Redis 内置了 16 个库,索引是 0-15 ,默认选择第 0 个 Redis 的常用命 ...

  5. 【使用篇二】SpringBoot异常处理(9)

    异常的处理方式有多种: 自定义错误页面 @ExceptionHandler注解 @ControllerAdvice+@ExceptionHandler注解 配置SimpleMappingExcepti ...

  6. springboot 入门二- 读取配置信息一

    在上篇入门中简单介绍下springboot启动使用了大量的默认配置,在实际开发过程中,经常需要启动多个服务,那端口如何手动修改呢? 此篇就是简单介绍相关的配置文件信息. Spring Boot允许外部 ...

  7. SpringBoot(二)Web整合开发

    Spring Boot (二):Web 综合开发 本篇文章接着上篇内容继续为大家介绍spring boot的其它特性(有些未必是spring boot体系桟的功能,但是是spring特别推荐的一些开源 ...

  8. SpringBoot学习(二)-->Spring的Java配置方式

    二.Spring的Java配置方式 Java配置是Spring4.x推荐的配置方式,可以完全替代xml配置. 1.@Configuration 和 @Bean Spring的Java配置方式是通过 @ ...

  9. SpringBoot 异常处理

    异常处理最佳实践 根据我的工作经历来看,我主要遵循以下几点: 尽量不要在代码中写try...catch.finally把异常吃掉. 异常要尽量直观,防止被他人误解 将异常分为以下几类,业务异常,登录状 ...

随机推荐

  1. 小白也能看懂的mySQL进阶【单表查询】

    目录 1.查询基础 SELECT语句基础 列的查询 为列设定别名 常数的查询 过滤表中重复数据 根据WHERE语句来选择记录 注释的书写方法 算术运算符和比较运算符 算术运算符 需要注意NULL 比较 ...

  2. cf div2 round 688 题解

    爆零了,自闭了 小张做项目入职字节 小李ak wf入职ms 我比赛爆零月薪3k 我们都有光明的前途 好吧,这场感觉有一点难了,昨天差点卡死在B上,要不受O爷出手相救我就boom zero了 第一题,看 ...

  3. Python中使用百分号占位符的字符串格式化方法中%s和%r的输出内容有何不同?

    Python中使用百分号占位符的字符串格式化方法中%s和%r表示需要显示的数据对应变量x会以str(x)还是repr(x)输出内容展示. 关于str和repr的关系请见: <Python中rep ...

  4. 转:解析HTTP协议六种请求方法,get,head,put,delete,post有什么区别

    解析HTTP协议六种请求方法,get,head,put,delete,post有什么区别 标准Http协议支持六种请求方法,即: 1.GET 2.POST 3.PUT 4.Delete 5.HEAD ...

  5. 第十四章 web前端开发小白学爬虫

    老猿从事IT开发快三十年了,接触互联网也很久了,但自己没有做过web前端开发,只知道与前端开发相关的一些基本概念,如B/S架构.html标签.js脚本.css样式.xml解析.cookies.http ...

  6. PyQt(Python+Qt)学习随笔:model/view架构中类QStandardItemModel的使用方法

    老猿Python博文目录 老猿Python博客地址 一.概述 QStandardItemModel是QAbstractItemModel的派生类,用于在Model/View架构中存储自定义数据的通用模 ...

  7. KafKa简介和利用docker配置kafka集群及开发环境

    KafKa的基本认识,写的很好的一篇博客:https://www.cnblogs.com/sujing/p/10960832.html 问题:1.kafka是什么?Kafka是一种高吞吐量的分布式发布 ...

  8. W12Scan和taoman批量刷edusrc(单机)

    昨天看到教育漏洞群里面发了利用w12scan和taoman两个开源工具批量刷edusrc的帖子链接, https://www.bugku.com/thread-3810-1-1.html 跟着帖子上面 ...

  9. linux替换项目jar包

    查看服务是否启动,如果启动,则需要根据 pid 停止服务: # ps -ef | grep xxx.jar 杀掉该项目进程 # kill -9 pid号 再次查看进程 # ps -ef | grep ...

  10. Scrum 冲刺第五天

    一.每日站立式会议 1.会议内容 1)进行每日工作汇报 张博愉: 昨天已完成的工作:学习如何编写测试计划 今日工作计划:学习如何编写用户手册 工作中遇到的困难:写文档也有很多讲究的点,花了很多时间 张 ...