参数校验别再写满屏的 if/else 了,差点被劝退……(下)

简介: 参数校验别再写满屏的 if/else 了,差点被劝退……(下)

5.自定义参数注解

5.1. 比如我们来个 自定义身份证校验 注解

@Documented
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = IdentityCardNumberValidator.class)
public @interface IdentityCardNumber {
    String message() default "身份证号码不合法";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

这个注解是作用在Field字段上,运行时生效,触发的是IdentityCardNumber这个验证类。


message 定制化的提示信息,主要是从ValidationMessages.properties里提取,也可以依据实际情况进行定制

groups 这里主要进行将validator进行分类,不同的类group中会执行不同的validator操作

payload 主要是针对bean的,使用不多。

5.2. 然后自定义Validator

这个是真正进行验证的逻辑代码:

public class IdentityCardNumberValidator implements ConstraintValidator<IdentityCardNumber, Object> {
    @Override
    public void initialize(IdentityCardNumber identityCardNumber) {
    }
    @Override
    public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {
        return IdCardValidatorUtils.isValidate18Idcard(o.toString());
    }
}

IdCardValidatorUtils在项目源码中,可自行查看

5.3. 使用自定义的注解

@NotBlank(message = "身份证号不能为空")
@IdentityCardNumber(message = "身份证信息有误,请核对后提交")
private String clientCardNo;

5.4.使用groups的校验

有的宝宝说同一个对象要复用,比如UserDTO在更新时候要校验userId,在保存的时候不需要校验userId,在两种情况下都要校验username,那就用上groups了:

先定义groups的分组接口Create和Update。

import javax.validation.groups.Default;
public interface Create extends Default {
}
import javax.validation.groups.Default;
public interface Update extends Default{
}

再在需要校验的地方@Validated声明校验组

/**
 * 走参数校验注解的 groups 组合校验
 *
 * @param userDTO
 * @return
 */
@PostMapping("/update/groups")
public RspDTO update(@RequestBody @Validated(Update.class) UserDTO userDTO) {
    userService.updateById(userDTO);
    return RspDTO.success();
}

在DTO中的字段上定义好groups = {}的分组类型

@Data
public class UserDTO implements Serializable {
    private static final long serialVersionUID = 1L;
    /*** 用户ID*/
    @NotNull(message = "用户id不能为空", groups = Update.class)
    private Long userId;
    /**
     * 用户名
     */
    @NotBlank(message = "用户名不能为空")
    @Length(max = 20, message = "用户名不能超过20个字符", groups = {Create.class, Update.class})
    @Pattern(regexp = "^[\\u4E00-\\u9FA5A-Za-z0-9\\*]*$", message = "用户昵称限制:最多20字符,包含文字、字母和数字")
    private String username;
    /**
     * 手机号
     */
    @NotBlank(message = "手机号不能为空")
    @Pattern(regexp = "^[1][3,4,5,6,7,8,9][0-9]{9}$", message = "手机号格式有误", groups = {Create.class, Update.class})
    private String mobile;
    /**
     * 性别
     */
    private String sex;
    /**
     * 邮箱
     */
    @NotBlank(message = "联系邮箱不能为空")
    @Email(message = "邮箱格式不对")
    private String email;
    /**
     * 密码
     */
    private String password;
    /*** 创建时间 */
    @Future(message = "时间必须是将来时间", groups = {Create.class})
    private Date createTime;
}

注意:在声明分组的时候尽量加上 extend javax.validation.groups.Default 否则,在你声明@Validated(Update.class)的时候,就会出现你在默认没添加groups = {}的时候的校验组@Email(message = "邮箱格式不对"),会不去校验,因为默认的校验组是groups = {Default.class}.


5.5.restful风格用法

在多个参数校验,或者@RequestParam 形式时候,需要在controller上加注@Validated。

@GetMapping("/get")
public RspDTO getUser(@RequestParam("userId") @NotNull(message = "用户id不能为空") Long userId) {
    User user = userService.selectById(userId);
    if (user == null) {
        return new RspDTO<User>().nonAbsent("用户不存在");
    }
    return new RspDTO<User>().success(user);
}
@RestController
@RequestMapping("user/")
@Validated
public class UserController extends AbstractController {
....圣洛代码...

6.总结

用起来很简单,soEasy,重点参与的统一结构体返回,统一参数校验,是减少我们代码大量的try catch 的法宝,我觉得在项目中,将异常处理好,并将异常做好日志管理,才是很好的升华,文章浅显,只是一个菜鸟的进阶笔记….


这里只是个人见解,技术菜,欢迎大佬不吝赐教……


相关文章
|
前端开发 Java 数据库连接
分组序列@GroupSequenceProvider、@GroupSequence控制数据校验顺序,解决多字段联合逻辑校验问题【享学Spring MVC】(中)
分组序列@GroupSequenceProvider、@GroupSequence控制数据校验顺序,解决多字段联合逻辑校验问题【享学Spring MVC】(中)
|
12月前
|
JSON API UED
运营商二要素验证 API:核验身份的一致性技术实践(Python示例)
随着线上业务快速发展,远程身份核验需求激增。运营商二要素验证API通过对接三大运营商实名数据,实现姓名、手机号、身份证号的一致性校验,具备权威性高、实时性强的优势,广泛应用于金融、电商、政务等领域。该接口支持高并发、低延迟调用,结合Python示例可快速集成,有效提升身份认证的安全性与效率。
1098 0
|
9月前
|
存储 缓存 安全
全网最全面介绍唯品会API接口指南
唯品会API助力开发者高效集成商品、订单、用户等功能。本指南详解注册、认证、调用步骤,提供Python示例与安全最佳实践,助你快速上手电商应用开发。(239字)
|
前端开发 Java 数据库连接
SpringBoot参数校验底层原理和实操。深度历险、深度解析(图解+秒懂+史上最全)
SpringBoot参数校验底层原理和实操。深度历险、深度解析(图解+秒懂+史上最全)
SpringBoot参数校验底层原理和实操。深度历险、深度解析(图解+秒懂+史上最全)
|
API 容器
Flutter UI组件库(JUI)
Flutter UI组件库(JUI)
3529 17
|
前端开发 Java
SpringBoot之自定义注解参数校验
SpringBoot之自定义注解参数校验
|
消息中间件 Kafka 数据处理
超硬核!详解Apache Hudi灵活的Payload机制
超硬核!详解Apache Hudi灵活的Payload机制
600 3
|
前端开发 Java 数据库连接
源码解析最流行的Validator框架——Hibernate Validator
源码解析最流行的Validator框架——Hibernate Validator
1007 0
源码解析最流行的Validator框架——Hibernate Validator
|
前端开发 安全 Java
一文弄懂spring validate
校验参数在以前基本都是使用大量的if/else,稍微方便一点的可以使用反射+自定义注解的形式,但是复用性不是很好,并且每个人对于的自定义注解有着自己的使用习惯,不过好在spring开发了validated框架用于注解校验,可以节省很多的校验ifelse代码,这篇文章通篇介绍了如何使用spring validated。
1105 10
Burpsuite系列 -- (PC端、手机端)抓包配置
Burpsuite系列 -- (PC端、手机端)抓包配置
516 0
Burpsuite系列 -- (PC端、手机端)抓包配置