Spring框架提供了接口参数校验的注解

添加validation依赖

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

Spring包下相关注解

看下@Validated注解源码

@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Validated {

上面说明此注解作用域:类、方法、参数上。

@Validated作用在方法参数上,就会对这个参数进行注解规则注解的校验:

实验:验证的User对象内部的注解校验规则使用

    @GetMapping("/testArgsAnno")
    @ResponseBody
    public void testArgsAnno(@Validated User user){
      
    }
@Data
public class User {
    @NotBlank(message = "名字不为空")
    @Length(max = 20, message = "账号[accountNo]长度过长")
    private String name;

    private String age;

    @Size(min = 6, max = 20, message = "密码长度必须在6-20之间")
    private String password;

    @NotBlank(message = "登录类型不允许为空")
    @Pattern(regexp = "1|2", message = "登录类型的取值不在指定范围内")
    private String loginType;

    @Max(value = 10,message = "用户区域不得大于10")
    @Min(value = 1,message = "用户区域不得小于0")
    private Integer areaId;

    @AssertFalse(message = "移动端必须是false,如果是true则报错")
    private Boolean isMobile;

    @AssertTrue(message = "PC端必须是true,如果是false则报错")
    private Boolean isPC;

    @Email(message = "必须是邮箱")
    private String eamil;
    @NotNull(message = "时间不能为空")
    @Past(message = "时间必须是过去的时间")
    private Date pastTime;

    @NotNull(message = "时间不能为空")
    @Future(message = "时间必须是未来的时间")
    private Date futureTime;

    @NotNull(message = "时间不能为空")
    @PastOrPresent(message = "校验时间必须是过去或现在的时间")
    private Date pastOrPresentTime;

    @NotNull(message = "时间不能为空")
    @FutureOrPresent(message = "校验时间必须是现在或未来的时间")
    private Date futureOrPresentTime;

    @NotEmpty(message = "NotEmpty是用来校验集合、Map、数组")
    private String[] hello;

    @DecimalMin(value = "0.01",inclusive = false,message = "金钱最小必须大于0.01")
    @DecimalMax(value = "9999.99",inclusive = true,message = "金钱最大只能到9999.99")
    private BigDecimal money;

    @Size(min = 1, max = 10, message = "items数量必须在1-10之间")
    private List<String> items;
}

此时如果请求接口,响应信息如下:这不是我们期望的结果!

{
    "timestamp": "2022-12-26T10:24:04.056+00:00",
    "status": 400,
    "error": "Bad Request",
    "path": "/abc/efg/testArgsAnno"
}

调整全局异常捕获并处理响应信息

我们一般在全局异常捕获BindException,这个异常!

    @ExceptionHandler({BindException.class})
    @ResponseBody
    public ResponseEntity BindException(HttpServletRequest req, BindException e) {
        logger.error("方法参数验证失败:{}", e.getMessage());
        BindingResult bindingResult = e.getBindingResult();
        return ResponseEntity.badRequest().body(bindingResult.getFieldError().getDefaultMessage());
    }

测试异常捕获信息

其他注解

@JsonFormat Jackson包下的时间格式工具

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss" , timezone = "GMT+8")
    private Date date;

非常规用法

枚举正则选择

定义一个性别枚举

@AllArgsConstructor  
public enum SexEnum {  

    MAN(1, "男"),  
    WOMAN(2,"女");  

    public final Integer code;  

    public final String desc;  

}

User类使用如下

    @NotNull(message = "请输入性别")  
    @EnumValid(enumClass = SexEnum.class, message = "输入性别不合法")  
    private Integer sex;  

分组校验

定义2个接口(里面什么都不写业务代码,仅仅作为区分不同校验场景下的标识)

CreateUserGroup

import javax.validation.groups.Default;

/**
 * @author : zanglikun
 * @date : 1/30/24 10:48
 * @desc : Copyright © zanglikun.com 此接口仅用于@Validation接口分组使用  https://www.zanglikun.com/15445.html
 */
public interface CreateUserGroup extends Default {

}

UpdateUserGroup

import javax.validation.groups.Default;

/**
 * @author : zanglikun
 * @date : 1/30/24 10:48
 * @desc : Copyright © zanglikun.com 此接口仅用于@Validation接口分组使用  https://www.zanglikun.com/15445.html
 */
public interface UpdateUserGroup extends Default {

}

UserRequestVO的具体实现

import com.zanglikun.springdataredisdemo.validate.group.user.CreateUserGroup;
import com.zanglikun.springdataredisdemo.validate.group.user.UpdateUserGroup;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;

/**
 * @author : zanglikun
 * @date : 1/30/24 10:50
 * @desc : Copyright © zanglikun.com
 */
public class UserRequestVO {
    @NotBlank(message = "请选择用户名", groups = CreateUserGroup.class)
    private String username;

    @NotBlank(message = "请输入密码", groups = UpdateUserGroup.class)
    @Size(max = 128, message = "密码过长,请重新设定密码!")
    private String password;
}

这里配置了创建的时候 用户名 不能为空。

更新的时候,没有限制。但是Size没有Group,所以也会执行Size的判定。

Controller验证如下:

package com.zanglikun.springdataredisdemo.validate;

import com.zanglikun.springdataredisdemo.validate.group.user.CreateUserGroup;
import com.zanglikun.springdataredisdemo.validate.group.user.UpdateUserGroup;
import com.zanglikun.springdataredisdemo.validate.vo.UserRequestVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author : zanglikun
 * @date : 1/30/24 10:52
 * @desc : Copyright © zanglikun.com
 */
@RestController
@RequestMapping("user")
@Validated
@Slf4j
@Api(value = "用户管理", tags = "用户管理")
public class UserControllerTestValidate {

    /**
     * 创建用户
     *
     * @param requestVO 用户信息
     * @return 创建成功
     */
    @ApiOperation(value = "创建用户", tags = "用户管理")
    @PostMapping("create")
    public ResponseEntity<String> createUser(@Validated(value = CreateUserGroup.class) @RequestBody UserRequestVO requestVO) {
        return ResponseEntity.ok("创建成功!");
    }

    /**
     * 更新用户
     *
     * @param requestVO 用户信息
     * @return 更新成功
     */
    @ApiOperation(value = "更新用户信息", tags = "用户管理")
    @PostMapping("update")
    public ResponseEntity<String> updateUser(@Validated(value = UpdateUserGroup.class) @RequestBody UserRequestVO requestVO) {
        return ResponseEntity.ok("更新成功!");
    }
}

附上结果:

特殊说明:
上述文章均是作者实际操作后产出。烦请各位,请勿直接盗用!转载记得标注原文链接:www.zanglikun.com
第三方平台不会及时更新本文最新内容。如果发现本文资料不全,可访问本人的Java博客搜索:标题关键字。以获取全部资料 ❤