参数校验别再写满屏的 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】(中)
|
5月前
|
JSON API UED
运营商二要素验证 API:核验身份的一致性技术实践(Python示例)
随着线上业务快速发展,远程身份核验需求激增。运营商二要素验证API通过对接三大运营商实名数据,实现姓名、手机号、身份证号的一致性校验,具备权威性高、实时性强的优势,广泛应用于金融、电商、政务等领域。该接口支持高并发、低延迟调用,结合Python示例可快速集成,有效提升身份认证的安全性与效率。
606 0
|
2月前
|
人工智能 自然语言处理 调度
24_BERT模型详解:从预训练到微调的全方位指南
BERT(Bidirectional Encoder Representations from Transformers)是由Google AI在2018年推出的革命性预训练语言模型,它彻底改变了自然语言处理(NLP)领域的格局。通过创新的双向训练方式,BERT能够捕捉词语在上下文环境中的完整语义信息,从而在各种下游任务中取得了突破性的表现。
|
5月前
|
前端开发 Java 数据库连接
SpringBoot参数校验底层原理和实操。深度历险、深度解析(图解+秒懂+史上最全)
SpringBoot参数校验底层原理和实操。深度历险、深度解析(图解+秒懂+史上最全)
SpringBoot参数校验底层原理和实操。深度历险、深度解析(图解+秒懂+史上最全)
|
Java Spring
@Async注解导致循环依赖,BeanCurrentlyInCreationException异常
@Async注解导致循环依赖,BeanCurrentlyInCreationException异常
302 2
|
人工智能 自然语言处理 搜索推荐
谈谈Function Calling
Function Calling赋予大语言模型调用外部工具的能力,弥补其缺乏行动力、信息滞后等缺陷。它像“指挥家”般,理解用户意图,选择合适的工具执行操作,并将结果反馈给用户,从而连接虚拟与现实。这一机制让大语言模型如虎添翼,更好地服务于人类。
854 3
谈谈Function Calling
|
API 容器
Flutter UI组件库(JUI)
Flutter UI组件库(JUI)
2628 17
|
存储 SQL Java
千万级的数据库查寻中,如何提高查询效率?
千万级的数据库查寻中,如何提高查询效率?
|
前端开发 Java
SpringBoot之自定义注解参数校验
SpringBoot之自定义注解参数校验