数据校验

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

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

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注解来指示需要对它们进行校验。此外,我们还为citystreetname等属性添加了其他的校验注解,如@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");  
        }  
    }  
}

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

相关推荐
wuyikeer1 小时前
Spring Framework 中文官方文档
java·后端·spring
Victor3561 小时前
MongoDB(61)如何避免大文档带来的性能问题?
后端
Victor3561 小时前
MongoDB(62)如何避免锁定问题?
后端
wuyikeer2 小时前
Spring BOOT 启动参数
java·spring boot·后端
子木HAPPY阳VIP3 小时前
Ubuntu 22.04 VMware 设置固定IP配置
人工智能·后端·目标检测·机器学习·目标跟踪
人间打气筒(Ada)3 小时前
如何基于 Go-kit 开发 Web 应用:从接口层到业务层再到数据层
开发语言·后端·golang
开心就好20253 小时前
使用Wireshark进行TCP数据包抓包分析:三次握手与四次挥手详解
后端·ios
用户4419395054873 小时前
OpenClaw服务器部署保姆级教程
后端
zdl6863 小时前
springboot集成onlyoffice(部署+开发)
java·spring boot·后端
Soofjan3 小时前
sync.Mutex讲解
后端