上文测试开发专题:如何在spring-boot中进行参数校验,我们讨论了如何使用@Min、@Max等注解进行参数校验,主要是针对基本数据类型和级联对象进行参数校验的演示,但是在实际中我们往往需要更为复杂的校验规则,比如注册用户的密码和确认密码进行校验,这个时候基本的注解就无法满足我们的要求了,需要去按照业务需求去自定义注解进行校验

元注解

在自定义注解之前我们有必要了解一些元注解,元注解就是在注解上的注解,可以对一个注解进行配置,元注解包括@Retention、@Target、@Document、@Inherited四种

  • @Retention,表示注解保留到什么时候,有以下三种模式

    • @Retention(RetentionPolicy.SOURCE) 表示注解仅存在于源码中,在class字节码文件中不包含
    • @Retention(RetentionPolicy.CLASS) 表示 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得
    • @Retention(RetentionPolicy.RUNTIME) 表示注解会在class字节码文件中存在,在运行时可以通过反射获取到 
  • @Target表示注解的作用目标是什么,只列出下面几个,剩余的大家自行谷歌把

    • @Target(ElementType.TYPE) 表示注解可以应用于接口、类、枚举、注解
    • @Target(ElementType.FIELD) 表示可以应用于字段、成员变量、枚举的常量等
    • @Target(ElementType.METHOD)表示可以作用于方法
  • @Document表示注解包含在javadoc中

  • @Inherited表示注解可以被继承

自定义校验注解

就以用户注册为例,我们需要校验密码和确认密码是否一致以及是否符合密码的规则,先新建一个PasswordEqual注解类

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Constraint(validatedBy = PasswordValidator.class)
public @interface PasswordEqual { String message() default "密码不一样"; Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}

下面我们来解释一下上面的注解,在PasswordEqual注解上,又标记了四个注解,前三个我们上面已经说过了。

这里说一下@Constraint注解,它表示这个注解是一个验证注解,并且通过validatedBy指定自定义校验注解的关联类,PasswordValidator类就是我们自定义的注解关联的类。

注解里面的groups和payload方法是模板方法,实现自定义注解必须写这么两个方法。

定义验证类

验证类里面包含具体的验证逻辑了,下面是一个简版的:

public class PasswordValidator implements ConstraintValidator<PasswordEqual, BannerCreateDto> {

    @Override
public boolean isValid(BannerCreateDto dto, ConstraintValidatorContext constraintValidatorContext) { return false;
}
}

这里需要对上面的代码进行一下说明,实现自定义校验类必须实现

ConstraintValidator接口,它是一个泛型接口,需要指定两个类型参数,第一个是自定义注解类型,第二个类型指定自定义注解修饰目标的类型,就是准备把自定义注解标记到什么类型上面。

必须重写isValid方法,所有的校验逻辑都在这个方法里面,下面我们简单写一下:

@Override
public boolean isValid(UserDto dto, ConstraintValidatorContext constraintValidatorContext) {
if (dto.getPassword().equals(dto.getConfirmPassword())){
return true;
}
return false;
}

然后我们将自定义的注解类标记到UserDto类上:

@Builder
@Getter
@Setter
@PasswordEqual
public class UserDto { @Length(min = 4, max = 10, message = "用户名长度必须在4-10个字符之间")
private String name; private String password; private String confirmPassword;
}

接下来我们在写一个简单的创建用户的接口:

@RestController
public class UserController { @PostMapping("/v2/user/create")
@ResponseBody
public UserDto createUser(@RequestBody @Validated UserDto dto){
return dto;
}
}

注意这里有要使用@ResponseBody能够返回自动序列化自定义对象,并且要写上 @Validated开启校验机制。

我们先输入正确的密码和确认密码一下:

可以看到能够正常的返回数据,这时再把两个密码改的不一样,试试:

这个时候就抛出了异常,这里的异常信息是因为进了全局异常处理器,不清楚的童鞋可以看下之前的文章。我们再来看一下控制台的输出:

控制台已经输出了校验的错误信息。

总结

我们今天介绍了自定义参数校验,并编写了校验注解和校验类,但是最后返回给用户的信息非常不友好,需要针对参数校验错误,能够返回定义的message,能够让有用户明白是哪里错了,下篇文章我们将介绍这块的内容,敬请关注!!

欢迎大家去 我的博客 瞅瞅,里面有更多关于测试实战的内容哦!!

更加灵活的参数校验,Spring-boot自定义参数校验注解的更多相关文章

  1. spring boot+自定义 AOP 实现全局校验

    最近公司重构项目,重构为最热的微服务框架 spring boot, 重构的时候遇到几个可以统一处理的问题,也是项目中经常遇到,列如:统一校验参数,统一捕获异常... 仅凭代码 去控制参数的校验,有时候 ...

  2. Spring Boot 2.X(四):Spring Boot 自定义 Web MVC 配置

    0.准备 Spring Boot 不仅提供了相当简单使用的自动配置功能,而且开放了非常自由灵活的配置类.Spring MVC 为我们提供了 WebMvcConfigurationSupport 类和一 ...

  3. 玩转Spring Boot 自定义配置、导入XML配置与外部化配置

    玩转Spring Boot 自定义配置.导入XML配置与外部化配置       在这里我会全面介绍在Spring Boot里面如何自定义配置,更改Spring Boot默认的配置,以及介绍各配置的优先 ...

  4. Spring boot 自定义 Resolver 支持 interface 类型参数

    在编写 RestController 层的代码时,由于数据实体类定义了接口及实现类,本着面向接口编程的原则,我使用了接口作为 RestController 方法的入参. 代码大致如下(省略具体业务部分 ...

  5. Spring Boot 自定义kafka 消费者配置 ContainerFactory最佳实践

    Spring Boot 自定义kafka 消费者配置 ContainerFactory最佳实践 本篇博文主要提供一个在 SpringBoot 中自定义 kafka配置的实践,想象这样一个场景:你的系统 ...

  6. Spring Boot自定义starter必知必会条件

    前言 在目前的Spring Boot框架中,不管是Spring Boot官方还是非官方,都提供了非常多的starter系列组件,助力开发者在企业应用中的开发,提升研发人员的工作效率,Spring Bo ...

  7. spring boot自定义线程池以及异步处理

    spring boot自定义线程池以及异步处理@Async:什么是线程池?线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务.线程池线程都是后台线程.每个线程都使 ...

  8. Spring boot 配置文件参数映射到配置类属性

    [参考文章]:SpringBoot之@EnableConfigurationProperties分析 [参考文章]:在Spring Boot中使用 @ConfigurationProperties 注 ...

  9. Spring Boot自定义配置与加载

    Spring Boot自定义配置与加载 application.properties主要用来配置数据库连接.日志相关配置等.除了这些配置内容之外,还可以自定义一些配置项,如: my.config.ms ...

  10. Spring Boot自定义Redis缓存配置,保存value格式JSON字符串

    Spring Boot自定义Redis缓存,保存格式JSON字符串 部分内容转自 https://blog.csdn.net/caojidasabi/article/details/83059642 ...

随机推荐

  1. Linux命令:chown

    说明: 将指定文件的拥有者改为指定的用户或组. 语法: chown [-cfhvR] [--help] [--version] user[:group] file... 参数: user : 新的文件 ...

  2. 2007 NOIP T1奖学金

    奖学金(07NOIPT1): [题目描述] 某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前5名学生发奖学金.期末,每个学生都有3门课的成绩:语文.数学.英语.先按总分从高到低排序,如果 ...

  3. 详解PHP反序列化中的字符逃逸

    首发先知社区,https://xz.aliyun.com/t/6718/ PHP 反序列化字符逃逸 下述所有测试均在 php 7.1.13 nts 下完成 先说几个特性,PHP 在反序列化时,对类中不 ...

  4. Mybatis Generator通用Join的实现

    通常,我们使用Mybatis实现join表关联的时候,一般都是通过在xml或注解里写自定义sql实现. 本文通过Mybatis Generator的插件功能新增一个JoinPlugin插件,只要在配置 ...

  5. Springboot:thymeleaf模板(八)

    存放位置:resources\templates 访问方式:通过Controller请求访问,不可直接访问(相当于web项目的WEB-INF目录) 环境依赖: <!--thymeleaf模板支持 ...

  6. MyBatis model、xml、mapper 自动生成,附源码

    Mybatis 代码自动生成 model.xml.mapper 代码结构图 代码地址 https://github.com/shootercheng/codegen 需要修改的地方见 readme

  7. SVM家族(一)

    SVM家族简史 故事要从20世纪50年代说起,1957年,一个叫做感知器的模型被提出, 1963年, Vapnikand Chervonenkis, 提出了最大间隔分类器,SVM诞生了. 1992年, ...

  8. 关于synergy的问题

    报错信息主要集中在以下两条: ERROR: ssl error occurred (system call failure) ERROR: eof violates ssl protocol 通过查找 ...

  9. 数字签名---RSA算法

    保证信息在传输过程中的安全性:             保密通信.密钥交换.数字签名.   RSA算法 Diffie-Hellman算法 DSA算法 保密通信 √ × × 密钥交换 √ √ × 数字签 ...

  10. ES6新增的Map和WeakMap 又是什么玩意?非常详细的解释

    上一篇文章讲了set和weakSet,这节咱就讲Map和weakMap是什么?这两篇文章并没有什么联系,主要知识用法类似而已.嘿嘿,是不是感觉舒服多了. 什么是Map 介绍什么是Map,就不得不说起O ...