2022-05-02 三.表单校验

图解

个人整理Xind图片导出:
请添加图片描述
参数校验:
请添加图片描述

简单例子

Java API 规范(JSR303)定义了 Bean 校验的标准 validation-api,但没有提供实现。Hibernate Validation 是对这个规范的实现,并增加了校验注解如 @Email、@Length等。Spring Validation 是对 Hibernate Validation 的二次封装,用于支持 Spring MVC 参数自动校验。接下来,我们以 spring-boot 项目为例,介绍 Spring Validation 的使用。

导入依赖
如果 spring-boot 版本小于 2.3.x,spring-boot-starter-web 会自动传入 hibernate-validator 依赖。如果 spring-boot 版本大于2.3.x,则需要手动引入依赖:

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.1.Final</version>
</dependency>

正常情况:

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

编写controller

/**
 * @Author zsl
 * @Date 2021/12/2 22:12
 */
@RestController
public class DemoController {
    @RequestMapping("add")
    public Map<String, Object> add(@RequestBody @Validated(AddGroup.class) Admin admin, BindingResult bindingResult) {
        System.out.println(admin);
        HashMap<String, Object> data = new HashMap<>();
        List<FieldError> fieldErrors = bindingResult.getFieldErrors();
        Integer i = 0;
        for (FieldError fe : fieldErrors) {
            data.put(fe.getField(), fe.getDefaultMessage());
        }
        return data;
    }

    @RequestMapping("edit")
    public String edit() {
        return "success";
    }
}

编写实体类

/**
 * @Author zsl
 * @Date 2021/12/2 22:13
 */
@Data
public class Admin {
    @NotNull(message = "用户id不能为空", groups = {EditGroup.class})
    @Null(message = "用户id必须为空", groups = {AddGroup.class})
    private Long id;
    @Pattern(regexp = "^[a-zA-Z0-9_-]{4,16}$", message = "用户名必须由字母开头数字下划线组成,且长度4-16", groups = {AddGroup.class, EditGroup.class})
    @NotBlank(message = "用户名不能为空", groups = {AddGroup.class, EditGroup.class})
    private String username;
    @GenderAnno(contains = {0, 1, 2}, message = "性别必须是0、1、2", groups = {AddGroup.class, EditGroup.class})
    @NotNull(message = "性别不能为空", groups = {AddGroup.class, EditGroup.class})
    private Integer gender;
    @Pattern(regexp = "^.*(?=.{6,})(?=.*\\d)(?=.*[A-Z])(?=.*[a-z])(?=.*[!@#$%^&*? ]).*$", message = "密码最少6位,包括至少1个大写字母,1个小写字母,1个数字,1个特殊字符", groups = {AddGroup.class, EditGroup.class})
    @NotBlank(message = "密码不能为空", groups = {AddGroup.class, EditGroup.class})
    private String password;
    @Email(message = "邮箱格式不正确", groups = {AddGroup.class, EditGroup.class})
    @NotBlank(message = "邮箱不能为空", groups = {AddGroup.class, EditGroup.class})
    private String email;
    @Pattern(regexp = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\\d{8}$", message = "手机格式不正确", groups = {AddGroup.class, EditGroup.class})
    @NotBlank(message = "手机不能为空", groups = {AddGroup.class, EditGroup.class})
    private String phone;
    @Past(message = "生日必须是一个过去的时间", groups = {AddGroup.class, EditGroup.class})
    @NotNull(message = "生日不能为空", groups = {AddGroup.class, EditGroup.class})
    private LocalDateTime birthday;
    @Pattern(regexp = "^[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$", message = "身份证格式不正确", groups = {AddGroup.class, EditGroup.class})
    @NotNull(message = "身份证不能为空", groups = {AddGroup.class, EditGroup.class})
    private String cardCode;
}

自定义注解:

/**
 * @Author zsl
 * @Date 2021/12/2 22:50
 */
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Constraint(validatedBy = {MyConstraintValidator.class})
public @interface GenderAnno {

    int[] contains() default { };

    String message() default "";

    Class<?>[] groups() default { };

    Class<? extends Payload>[] payload() default { };
}

自定义注解实现规则

/**
 * @Author zsl
 * @Date 2021/12/2 22:52
 */
public class MyConstraintValidator implements ConstraintValidator<GenderAnno, Integer> {

    private List<Integer> contains;

    /**
     * 初始化 将注解需要包含的值保存到 当前对象中
     */
    @Override
    public void initialize(GenderAnno constraintAnnotation) {
        ArrayList<Integer> ints = new ArrayList<>();
        int[] contains = constraintAnnotation.contains();
        for (int i = 0; i < contains.length; i++) {
            ints.add(contains[i]);
        }
        this.contains = ints;
    }

    /**
     * 校验是否包含
     */
    @Override
    public boolean isValid(Integer value, ConstraintValidatorContext context) {
        return contains.contains(value);
    }
}

当然表单验证失败时,会抛异常,而异常会统一在异常处理中解决,详情请看全局统一异常处理文章

表单校验异常

抛出异常,在全局异常控制管理中进行处理。

    /**
     * 处理表单校验异常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseResult<String> handlerFormValidException(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        List<FieldError> fieldErrors = bindingResult.getFieldErrors();
        ...
        return ResponseResult.error(...);
    }

下一篇跳转:4.全局异常处理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值