Spring 统一参数校验(Validator + BindingResult)

本文详细介绍了如何在Java项目中使用javax.validation.constraints包下的注解进行参数校验,包括常见注解的使用方法,示例代码展示,以及利用@ControllerAdvice和AOP进一步封装校验逻辑的技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 简介

Java项目传参时,可能有许多字段都需要进行校验,可以通过javax.validation.constraints.*包下的注解,再配合 @Valid 和 BindingResult 进行错误信息的返回。
在这里插入图片描述

2. 示例代码

Validator可以非常方便的制定校验规则,并自动帮你完成校验。首先在入参里需要校验的字段加上注解,每个注解对应不同的校验规则,并可制定校验失败后的信息:

import javax.validation.constraints.*;

/**
 * 用户实体类
 */
public class UserBean {
    @NotNull(message = "用户id不能为空")
    private String id;

    @NotNull(message = "用户名称不能为空")
    @Size(max = 50, message = "用户名称最大支持50个字符")
    private String name;

    @Max(value = 100, message = "年龄不能大于100")
    @Min(value = 0, message = "年龄不能小于0")
    private int age;

    @Max(value = 1, message = "性别只能为0/1")
    @Min(value = 0, message = "性别只能为0/1")
    private String sex;

    @Email(regexp = ".*@qq.com", message = "邮箱格式不正确")
    private String email;

    @Size(max = 11, message = "电话号码最大支持11个字符")
    private String phone;

    public UserBean() {
    }

    public UserBean(String id, String name, int age, String sex, String email, String phone) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.email = email;
        this.phone = phone;
    }

   // getter、setter

    @Override
    public String toString() {
        return "UserBean{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                ", email='" + email + '\'' +
                ", phone='" + phone + '\'' +
                '}';
    }
}

校验规则和错误提示信息配置完毕后,接下来只需要在接口需要校验的参数上加上 @Valid 注解,并添加 BindingResult 参数。Controller层通过对标注有@Valid的JavaBean进行校验,并将校验结果封装在BindingResult 中。

注意@Valid 和 BindingResult 是一一对应的,如果有多个@Valid,那么每个@Valid后面都需要跟一个 BindingResult 用于接收 JavaBean 的校验信息。

	@PostMapping("testValid.do")
    public String testValid(@RequestBody @Valid UserBean user, BindingResult bindingResult) {
        // 如果有参数校验失败,会将错误信息封装成对象组装在BindingResult里
        for (ObjectError error : bindingResult.getAllErrors()) {
            return error.getDefaultMessage();
        }
        return "success";
    }

3. 常用校验注解

  • @Null 被注释的元素必须是null
  • @NotNull 被注释的元素不能为null
  • @AssertFalse 被注释的元素必须为false
  • @AssertTrue 被注释的元素必须是true


    (字符串/数组/集合)校验:
  • @Pattern(regexp=“reg”) 被注释的元素必须符合给定的正则表达式
  • @Size(max, min) 被注释的元素的长度必须在范围内
  • @NotEmpty 被注释的元素不为空或者null
  • @NotBlank 被注释的元素不为null或者trim()后不为空
  • @Email 验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式


    数值校验:
  • @Max(value) 被注释的元素必须是一个数字,并且小于或者等于指定的int值
  • @Min(value) 被注释的元素必须是一个数字,并且大于或等于指定的int值
  • @DecimalMax(value) 被注释的元素必须是一个数字,并且小于或者等于指定的值
  • @DecimalMin(value) 被注释的元素必须是一个数字,并且大于或等于指定的值
  • @Digits(integer, fraction) 被注释的元素必须是一个数字, 精整数度小于等于integer;小数部分精度小于fraction
  • @Range(min=long1, max=long2) 被注释的元素必须是一个数字,其值必须>=long1,并且<=long2
  • @Digits(integer,fraction) 限制必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction


    日期校验:Date/Calendar
  • @Post 被注释的元素必须是一个过去的日期
  • @Future 被注释的元素必须是一个未来的日期

4. 使用AOP(@Aspect)或@ControllerAdvice进一步封装

在实际开发中,还会进行更深层次的封装,因为这样代码编写很麻烦,并且重复代码很多。

4.1 @ControllerAdvice封装

关于 @ControllerAdvice 的用法可以参考《SpringMVC 中 @ControllerAdvice 注解》

Validator + 自动抛出异常

	@PostMapping("testValid.do")
    public String testValid(@RequestBody @Valid UserBean user) {
        return "success";
    }

当传递一个不符合校验规则的参数给接口,程序会引发 org.springframework.web.bind.MethodArgumentNotValidException 异常。这时候,就是ControllerAdvice发挥作用的时候了。

@ControllerAdvice
public class TestControllerAdvice {

    @ExceptionHandler({MethodArgumentNotValidException.class})
    public ModelAndView customException(MethodArgumentNotValidException e) {
        ModelAndView mv = new ModelAndView();
        // 获取参数校验失败信息
        List<ObjectError> list = e.getBindingResult().getAllErrors();
        StringBuffer errorMsg = new StringBuffer();
        for (ObjectError error : list){
            errorMsg.append(error.getDefaultMessage() + "\n");
        }
        mv.addObject("description", errorMsg.toString());
        // 返回一个错误页面
        mv.setViewName("error");
        return mv;
    }
}

上面代码会自动处理程序的 MethodArgumentNotValidException 异常,给出友好的代码提示。

4.2 AOP(@Aspect)封装

关于 @Aspect 的用法可以参考《Spring AOP配置 之 @Aspect》

controller代码:

	@PostMapping("testValid.do")
    public String testValid(@Valid UserBean user, BindingResult bindingResult) {
        return "success";
    }

AOP类:

@Aspect
@Component
public class ValidAOP {
    // 定义切点
    private final String POINT_CUT = "execution( * com.web..controller.*.*(..))";

    @Pointcut(value = POINT_CUT)
    public void pointCut() {
    }

    @Around(value = "pointCut() && args(.., bindingResult)")
    public Object around(ProceedingJoinPoint proceedingJoinPoint, BindingResult bindingResult) throws Throwable {
        Object obj = null;
        if (bindingResult.hasErrors()) {
            List<ObjectError> errors = bindingResult.getAllErrors();
            StringBuffer sb = new StringBuffer();
            for (ObjectError error : errors) {
                sb.append(error.getDefaultMessage() + "\n");
            }
            obj = sb.toString();
        } else {
            obj = proceedingJoinPoint.proceed();
        }
        return obj;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值