参数校验别再写满屏的 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 的法宝,我觉得在项目中,将异常处理好,并将异常做好日志管理,才是很好的升华,文章浅显,只是一个菜鸟的进阶笔记….


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


相关文章
|
12月前
|
存储 编译器 C语言
还在为每次打开程序的输入烦恼吗,这篇文章让你不在迷茫
在之前我们编写的程序中,我们总要录入一些数据给予程序用于计算,但是当我们退出程序后录入的数据会销毁,因为此时数据都是存放在内存中。等到下次再运行程序时,数据又得从新录入,这样就非常的难受。
44 0
还在为每次打开程序的输入烦恼吗,这篇文章让你不在迷茫
|
10月前
|
安全 测试技术
不会写测试用例咋办?牢记这5点,你也能写出高逼格案例
不会写测试用例咋办?牢记这5点,你也能写出高逼格案例
|
存储 编解码 数据处理
还在为搞不懂笔记本电脑参数而苦恼么?一篇文章就够啦
还在为搞不懂笔记本电脑参数而苦恼么?一篇文章就够啦
245 4
|
Java 程序员 开发者
只用一行代码,你能玩出什么花样?
只用一行代码,你能玩出什么花样?
77 1
|
开发者
试着做点儿有趣的事情
一个游戏怎样才算是做完了?这是个因人而异的问题。有些游戏还没有做出来就做完了,因为开发者不想再做了。有的游戏看上去做完了,但是后续还在不停的更新,那我们就说这个游戏其实还没有做完。至于如何算是做完了,我觉得这应该交由该游戏的制作者来决定。
61 0
|
存储 自然语言处理 JavaScript
产品让我限制一下输入框字数,结果我搞了3天没搞明白
作为一名新人er,看到自己的文章列表空空如也总觉得不是那么回事。但是想动手写点什么吧,脑子里实在又憋不出什么料。写一篇正儿八经的技术文章真的是好难好麻烦,尤其是看了首页推荐的大佬文章,更是觉得自己那点东西就别拿出去丢人了。有充分借口的日子总是短暂而且美好。这不,就在不久前的一次组会上,老大们又提起了”写点什么“的事儿,并且一再强调,不需要写出个什么宏文出来,写点什么都行。你看这台阶都给到这了,不下
|
Python
上古代码漫游记(二):把陷阱去掉了,反倒踩进了新的陷阱?
上古代码漫游记(二):把陷阱去掉了,反倒踩进了新的陷阱?
90 0
|
前端开发 Java Spring
求求你不要写满屏的 try...catch 了,这才是优雅的处理方式,真香...
求求你不要写满屏的 try...catch 了,这才是优雅的处理方式,真香...
238 0
求求你不要写满屏的 try...catch 了,这才是优雅的处理方式,真香...
|
Java 数据库连接 Spring
参数校验别再写满屏的 if/else 了,差点被劝退……(上)
参数校验别再写满屏的 if/else 了,差点被劝退…(上)
105 0
参数校验别再写满屏的 if/else 了,差点被劝退……(上)
找不到“妹”字在哪?一款游戏看把你愁的,用我这个代码逻辑,不再被游戏困扰!
找不到“妹”字在哪?一款游戏看把你愁的,用我这个代码逻辑,不再被游戏困扰!
136 0
找不到“妹”字在哪?一款游戏看把你愁的,用我这个代码逻辑,不再被游戏困扰!