数据校验

在日常开发中,我们有时候需要对一些参数进行校验,此时需要书写大量的逻辑判断,会显得代码比较冗余(如图所示)。

此时可以使用如下注解方式来简化代码。

Valid注解方式

引入相关依赖

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
    <version>3.2.1</version>
</dependency>
java 复制代码
@Data
public class ModifyNameReq {
    @NotBlank
    @Size(max = 6,message = "名称不能太长哦!")
    private String name;
    @NotBlank
    @Size(max = 6,message = "名称不能太长哦!")
    private String address;
    @NotBlank
    private String img;
}

@Valid要加上,否则会没有效果,校验不了

java 复制代码
@RestController
public class EurekaServerController {
    @PostMapping("test")
    public String save(@Valid @RequestBody ModifyNameReq nameReq){
        return "OK";
    }
}

使用postman进行测试

此时如果不配置异常处理器,会出现如下错误。所以为了更好的显示和更友好的提醒用户可以配置异常处理器。

异常处理器

java 复制代码
@RestControllerAdvice  // 监听打了@RestController注解的Controller
public class GlobalExceptionHandler {
    /**
     * validation参数校验异常
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class) // 监听该类型的错误
    public ApiResult<?> methodArgumentNotValidException(MethodArgumentNotValidException exception){
        StringBuilder errorMsg = new StringBuilder();
        exception.getBindingResult().getFieldErrors() // 获取所有错误字段信息
                .forEach(item->errorMsg.append(item.getField()).append(item.getDefaultMessage()));
        return ApiResult.fail(CommonErrorEnum.PARAM_VALID.getCode(),errorMsg.substring(0,errorMsg.length() -1));
    }
}

上述代码中,大家只需要了解如何获取错误字段信息即可,前面的ApiResult只是用来封装返回给前端结果的工具类

此时有的小伙伴就又会说了,那我如果是对象里面包含了一个对象,也需要进行数据的校验怎么办呢?此时我们就可以采取下面的方式了。

java 复制代码
@Data
public class ModifyNameReq {
    @NotBlank
    @Size(max = 6,message = "名称不能太长哦!")
    private String name;
    @NotBlank
    private String img;
    @Valid // 这个注解会触发Address对象的校验  
    private Address address;
}
java 复制代码
@Data
public class Address {
    @NotBlank(message = "城市不能为空")
    @Size(max = 50, message = "城市名称不能超过50个字符")
    private String city;  
      
    @NotBlank(message = "街道不能为空")  
    @Size(max = 100, message = "街道名称不能超过100个字符")  
    private String street;  
}

此时我们并没有输入street字段,此时看看会出现什么错误呢?

大家可以很清晰地看见我们的嵌套的校验生效了。

此时又有小伙伴们说了,那么如果对象里面包含一个集合对象呢

java 复制代码
@Data
public class ModifyNameReq {
    @NotBlank
    @Size(max = 6,message = "名称不能太长哦!")
    private String name;
    @NotBlank
    private String img;
    @Valid // 这个注解会触发Address对象的校验  
    private List<Address> address;
}

此时发送请求,出现的异常会跟上述异常相同。

非注解方式

在上面的示例中,ModifyNameReq类包含了一个Address类型的属性和一个Address类型的列表属性。对于这两个属性,我们都使用了@Valid注解来指示需要对它们进行校验。此外,我们还为city、street和name等属性添加了其他的校验注解,如@NotNull和@Size。

要使用这些校验注解,还需要配置一个校验器(Validator),并在需要的时候调用它来执行校验。这通常是通过Spring框架自动完成的,但是也可以手动创建和使用Validator实例。以下是一个简单的示例,展示了如何手动使用Validator来校验ModifyNameReq对象:

java 复制代码
import javax.validation.ConstraintViolation;
import javax.validation.Validation;  
import javax.validation.Validator;  
import javax.validation.ValidatorFactory;
public class ValidationExample {  
  
    public static void main(String[] args) {  
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();  
        Validator validator = factory.getValidator();

        ModifyNameReq modifyNameReq = new ModifyNameReq();
        modifyNameReq.setImg("http:132.png");
        modifyNameReq.setName("手动创建使用Validator实例");
        Address address = new Address();
        address.setCity("北京");
        modifyNameReq.setAddress(Arrays.asList(address));
        Set<ConstraintViolation<ModifyNameReq>> violations = validator.validate(modifyNameReq);
        if (!violations.isEmpty()) {  
            for (ConstraintViolation<ModifyNameReq> violation : violations) {
                System.out.println(violation.getMessage());  
            }  
        } else {  
            System.out.println("Validation succeeded");  
        }  
    }  
}

此时大家可以运行这段代码,看看会有什么信息打印出来吧。

相关推荐
我命由我1234513 分钟前
5-2.Python 编码进阶 - 字符串进阶(拼接、普通格式化、普通格式化数字精度控制、快速格式化、遍历、常用方法)
java·开发语言·后端·python·学习·java-ee·学习方法
专业程序开发源14 分钟前
django视听资源推荐系统16690-计算机课程设计、毕业设计
vue.js·spring boot·后端·python·django·php·课程设计
多客:duokelijie17 分钟前
婚恋交友小程序合规梳理:上线运营需要准备哪些资质与许可手续?
后端·mysql·微信小程序·前端框架·uni-app·php·持续部署
yunwei3721 分钟前
eBPF 实例教程:使用内核跟踪点监控 GPU 驱动活动
linux·后端·性能优化
高频因子挖掘机27 分钟前
别再手动维护股票名称映射表:用 Python 查询交易所元数据
后端·github·api
我的xiaodoujiao28 分钟前
Django 权限系统项目实战详细图文教程 2--环境搭建
后端·python·django
高频因子挖掘机1 小时前
QuantDash 明明安装成功,为什么 Python 还是无法 import?
后端·github·api
Java爱好狂.9 小时前
Java初学者如何一周速通SpringBoot!
java·spring boot·后端·spring·高并发·架构师·java面试
马良神笔11 小时前
2026 年Rag最近技术前沿总结
后端·python·django
程序猿DD11 小时前
同样10美元,OpenDesign和Command Code的DeepSeek V4.1 Flash额度到底有多少?
后端