参数校验机制

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. JZOJ2020年8月7日提高组反思

    JZOJ2020年8月7日提高组反思 T1 暴力枚举 枚举起点和\(p\) 然后就 过了?! 根据本人不严谨的推算 时间复杂度\(O(\dfrac{n^7}{4})\) 数据太水就过去了QAQ T2 ...

  2. 浅尝 Elastic Stack (三) Logstash + Beats

    本文使用 Filebeat,如果没有安装需要安装: curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat- ...

  3. Java 生成有序 UUID

    UUID.randomUUID() 生成的 UUID 是无序的,如果作为数据主键,不利于索引 Hibernate 的 UUIDHexGenerator.generate() 方法可以生成有序的 UUI ...

  4. ccpc赛前记

    距离ccpc比赛还不到一个小时了,有些紧张又有些兴奋 作为留学选手参加国内的比赛感觉好像很奇怪?谁能想到一个疫情会让我拿ccpc结束自己的acm生涯(也许,谁知道呢) cf上蓝了 该准备gre了,目标 ...

  5. 第三十三章、PyQt+moviepy实现的MP4视频转gif工具

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 一.引言 在写<第三十二章.使用splitDockWidget和 ...

  6. 剑指offer二刷——数组专题——斐波那契数列

    题目描述 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0,第1项是1). n<=39 我的想法 斐波那契数列定义:F(0)=0,F(1)=1, ...

  7. AcWing 1194. 岛和桥

    \(f[s][i][j]\) 表示一条有向路径(不经过重复点),当前路径点集合为 \(s\),最后两个点是 \(j\) → \(i\) 的最大价值 \(g[s][i][j]\) 类似,不过是方案数. ...

  8. P5785 [SDOI2012]任务安排

    本题解用于本蒟蒻加深算法印象,也欢迎大家阅读 本篇题解将分为四块,一步一步地讲解本题, Part 1: O(n^3) \(n^3\) 算法应该非常的显然,我们设 \(f_{i,j}\) 为到 \(i\ ...

  9. CF873D Merge Sort

    其实最优的方法其他的题解已经讲得很好了,本题解仅用于记录和分享一个新的思路. 这道题是让你输出符合条件的序列,而序列的每个数之间具有一定的逻辑关系,很容易想到拓扑排序,于是此题就变为,如何找出满足条件 ...

  10. uni-app中组件的使用

    组件基本知识点: uniapp中:每个页面可以理解为一个单页面组件,这些单页面组件注册在pages.json里,在组件关系中可以看作父组件. 自定义可复用的组件,其结构与单页面组件类似,通常在需要的页 ...