张国伟 发表于 2024-5-12 18:32:57

SpringMVC实现参数校验

在 Web 应用的三层架构中,确保在表述层(Presentation Layer)对数据进行检查和校验是非常重要的。精确的数据校验可以确保业务逻辑层(Business Logic Layer)基于有效和合法的数据进行处理,同时将错误的数据隔离在业务逻辑层之外。这有助于提高系统的健壮性、安全性和可维护性。
校验概述

JSR-303是Java EE 6中的一项子规范,也被称为Bean Validation。这个规范主要用于对Java Bean中的字段值进行验证。JSR-303提供了一套注解和API,方便开发者在实体类中对字段进行验证,以确保数据的合法性。
在JSR-303中,内置了许多常用的约束规则,如@NotNull(非空验证)、@Size(长度验证)、@Range(范围验证)等。这些注解可以直接应用于实体类的字段上,以声明验证规则。同时,JSR-303还提供了验证器(Validator)接口,用于实行验证操作。开发者可以通过注入Validator实例,大概使用Validation工具类来触发验证。
在Spring MVC中,JSR-303得到了很好的支持。开发者可以在控制器的方法参数上使用JSR-303的注解,以实现表单数据的主动验证。当表单数据不符合验证规则时,Spring MVC会主动抛出异常,并将错误信息绑定到相应的字段上,方便前端展示错误信息。
常用注解

@NotNull:确保字段值不为null。
@NotBlank:用于String类型参数校验,检查字符串不能为null且去除首尾空格后长度大于0。
@NotEmpty:主要用于集合校验,校验集合不能为null且size大于0,也可以用于String的校验,确保字
@Null:确保字段值为null。
@AssertTrue 和 @AssertFalse:用于boolean字段,确保字段值为true或false。
@Min 和 @Max:用于Number和String字段,确保字段值在指定的范围内。
@DecimalMin 和 @DecimalMax:用于BigDecimal,BigInteger,String,byte,short,int,long字段,确保字段值在指定的小数范围内。需要注意的是,小数验证存在精度题目。
@Size:用于Collection,Map,Array,String字段,确保字段的长度(或大小)在指定的范围内。
@Digits:用于BigDecimal,BigInteger,String,byte,short,int,long字段,验证值的数字构成是否合法。它有两个参数,integer表示整数部分的数字的位数,fraction表示小数部分的数字的位数。
@Email:用于String字段,验证字段值是否为有效的电子邮件所在。
@Past 和 @Future:用于日期和时间字段,确保日期在过去或未来。
@Pattern:用于String字段,验证字段值是否匹配指定的正则表达式。
@Range:控制一个数值的范围,如数字、日期等。
@Valid:递归地对关联对象进行校验,如果关联对象是个集合大概数组,那么对其中的元素进行递归校验;如果是一个map,则对其中的值部分进行校验。
@CreditCardNumber:信用卡验证。
@URL:验证一个字符串是否符合URL格式。
@ScriptAssert:使用脚本语言进行自定义验证。
操作演示

1.导入依赖
<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.1.5.Final</version>
</dependency>

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.1.Final</version>
</dependency>

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator-annotation-processor</artifactId>
    <version>6.1.5.Final</version>
</dependency>2.校验实体对象参数
实体类
@Data
public class User {

    @NotBlank
    private String name;
    @NotNull(message = "年龄最小1岁,最大100岁")
    @Range(min = 1 , max = 100)
    private Integer age;
    @NotNull(message = "邮箱不能为空,并且要符合规范")
    @Email
    private String email;
    @NotNull
    @Size(min = 2,max = 50)
    private String address;
    @Past
    private Date birthday;
    @NotEmpty
    private List<String> users;
}controller
//实体对象校验
//在实体类参数和 BindingResult 之间不能有任何其他参数, BindingResult可以接受错误信息,避免信息抛出!
//@Validated 或 @Valid 代表应用校验注解!
@PostMapping("validateObject")
private String validateObject(@Valid @RequestBody User user, BindingResult result) {
        //判断是否有信息绑定错误! 有可以自行处理!
        if (result.hasErrors()) {
                String errorMsg = Objects.requireNonNull(result.getFieldError()).toString();
                System.out.println(errorMsg);
                return "error";
        }
        System.out.println("user=" + user);
        return "success";
}说明:
@Validated注解是SpringMVC提供的。
@Valid注解是JSR-303提供的。
3.根本类型校验
    //基本类型校验
@GetMapping("validate")
public String validateBasic(@RequestBody @Min(18) Integer age, @RequestBody @NotBlank String name) {
    return "success";
}开启校验规则

基于xml配置方式
基于配置类方式
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Bean
    public Validator validator() {
      ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
      return factory.getValidator();
    }
}4.集合校验
//集合校验
@PostMapping("validateList")
public String validateList(@Valid @RequestBody List<@Positive User> users,BindingResult result) {
        if (result.hasErrors()) {
                System.out.println(Objects.requireNonNull(result.getFieldError()).toString());
                return "error";
        }
        return "success";
}自定义校验注解

1.定义一个注解类,并使用@interface关键字。
2.在注解类上添加@Constraint注解,并指定校验器类。
@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@Constraint(validatedBy = MyCustomValidator.class)public @interface MyCustomValidation {    String message() default "该字段不能为空";    Class[] groups() default {};    Class
页: [1]
查看完整版本: SpringMVC实现参数校验