2022-05-02 表单校验

2022-05-02 表单校验,第1张

表单校验
  • 图解
  • 简单例子
  • 表单校验异常

图解

个人整理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.hibernategroupId>
    <artifactId>hibernate-validatorartifactId>
    <version>6.0.1.Finalversion>
dependency>

正常情况:

<dependencies>
    <dependency>
        <groupId>org.projectlombokgroupId>
        <artifactId>lombokartifactId>
    dependency>

    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-validationartifactId>
    dependency>

    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
    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 = "身份z格式不正确", groups = {AddGroup.class, EditGroup.class})
    @NotNull(message = "身份z不能为空", 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.全局异常处理

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/801350.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-07
下一篇 2022-05-07

发表评论

登录后才能评论

评论列表(0条)

保存