springboot(十四)参数校验

本文介绍如何使用Spring Boot结合JSR303/JSR349和hibernate-validator进行参数校验,包括常见注解的使用及自定义提示信息。

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

前言:

       在开发过程中,为了防止我们接口传递的参数影响我们的程序正常运行,我们少不了验证判断。虽然可以在前端来做验证。但是也避免不了他人恶意行为。所以,后台验证是必不可少的。

      Spring Boot 支持JSR303/JSR349验证框架,通过注解实现对参数的校验,并将校验结果封装成BindingResult对象。

      hibernate validator(官方文档)提供了一套比较完善、便捷的验证实现方式。

常用注解:

检查类型 注解      说明
空检查@Null验证对象为null
@NotNull验证对象不为null
@NotEmpty 验证对象不为null、且长度>0
@NotBlank 验证字符串不为null、且最少有一个非空格字符
长度检查 @Size(min,max)验证对象长度
@Length(min,max) 验证字符串长度
数值检查@Min(value) 验证数字>=value
@Max(value)   验证数字<=value
@Digits(integer,fraction) 验证数字格式
@Range(min,max)  验证数字是否符合[min,max]
正则检查@Pattern(regexp) 验证字符串是否符合正则表达式
@Email    验证是否邮箱格式

实现:

新建项目:springboot-validation,pom.xml

<dependencies>
		<!--web-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.22</version>
        </dependency>
    </dependencies>

          注:这里可能你会很奇怪为什么不引入参数校验 hibernate validator的包呢?那是因为我们的sprinboot-start-web里面已经集成了我们的 hibernate validator,我们可以进入sprinboot-start-web里面可以看到。没错就是它啦!大家可以点进springboot的每个包中多看看都集成了什么!

              

编写自定义提示码类:CodeMsg.java,这里的提示码大家都可以根据自己的需求来定的。

@Data
public class CodeMsg {
	private int code;
	private String msg;
	//错码定义误
	public static CodeMsg SUCCESS = new CodeMsg(0, "success");
	public static CodeMsg SERVER_ERROR = new CodeMsg(50000, "服务端异常");
	public static CodeMsg BIND_ERROR = new CodeMsg(50001, "参数校验异常:%s");
	public static CodeMsg REQUEST_ILLEGAL = new CodeMsg(50002, "请求非法");
	
	private CodeMsg( int code,String msg ) {
		this.code = code;
		this.msg = msg;
	}
	
	public CodeMsg fillArgs(Object... args) {
		int code = this.code;
		String message = String.format(this.msg, args);
		return new CodeMsg(code, message);
	}
	
}

自定义返回格式类:Result.java

@Data
public class Result<T> {
	//提示码
	private int code;
	//消息
	private String msg;
	//返回提示
	private T data;
	
	/**
	 *  成功时候的调用
	 * */
	public static  <T> Result<T> success(T data){
		return new Result<T>(data);
	}
	
	/**
	 *  失败时候的调用
	 * */
	public static  <T> Result<T> error(CodeMsg codeMsg){
		return new Result<T>(codeMsg);
	}
	
	private Result(T data) {
		this.data = data;
	}
	
	private Result(int code, String msg) {
		this.code = code;
		this.msg = msg;
	}
	
	private Result(CodeMsg codeMsg) {
		if(codeMsg != null) {
			this.code = codeMsg.getCode();
			this.msg = codeMsg.getMsg();
		}
	}
 
}

         注:说明一下为什么需要这两个类,这是为了让我们的开发更加规范。让我们接口返回提示更加友好。

编写对象:TestVo.java,里面的注解大家看上面的注解介绍就知道啦

@Data
public class TestVo {
    @NotBlank(message = "姓名不能为空")
    private String name;

    @NotNull(message = "年龄必填")
    @Max(value = 20,message = "年龄必须小于20")
    @Min(value = 0,message = "年龄必须大于0")
    private Integer age;
}

编写验证工具类:BindingResultUtil.java

public class BindingResultUtil {

    /**
     * 多个参数验证提示
     * @param bindingResult
     * @return
     */
    public static Result bindingResults(BindingResult bindingResult){
        Map<String, String> errorMsg = new HashMap<String, String>();
        List<FieldError> fieldErrors = bindingResult.getFieldErrors();
        for(FieldError fieldError:fieldErrors){
            errorMsg.put(fieldError.getField(), fieldError.getDefaultMessage());
        }
        return Result.error(CodeMsg.BIND_ERROR.fillArgs(errorMsg));
    }

    /**
     * 单个参数验证提示
     * @param bindingResult
     * @return
     */
    public static Result bindingResult(BindingResult bindingResult){
        return Result.error(CodeMsg.BIND_ERROR.fillArgs(bindingResult.getFieldError().getDefaultMessage()));
    }
}

         注:BindingResult用于接收我们提示信息。假如某个参数不满足条件,我们可以通过它来接收相应的提示信息!

编写测试类TestController.java

@RestController
public class TestController {
    private final Logger logger= LoggerFactory.getLogger(TestController.class);

    /**
     * 返回所有不满足验证参数的提示
     * @param testVo
     * @param bindingResult
     * @return
     */
    @GetMapping("/test")
    public Result<TestVo> test(@Valid TestVo testVo , BindingResult bindingResult) {
        //判断是否有错,是否有不满足校验的参数
        if (bindingResult.hasErrors()) {
            //返回多个提示信息
            return BindingResultUtil.bindingResults(bindingResult);
        }
        logger.info("testVo={}"+testVo.toString());
        return Result.success(testVo);
    }

    /**
     * 只返回一个不满足验证参数的提示
     * @param testVo
     * @param bindingResult
     * @return
     */
    @GetMapping("/test1")
    public Result<TestVo> test1(@Valid TestVo testVo ,BindingResult bindingResult) {
        //判断是否有错,是否有不满足校验的参数
        if (bindingResult.hasErrors()) {
            //返回单个提示信息
            return BindingResultUtil.bindingResult(bindingResult);
        }
        logger.info("testVo={}"+testVo.toString());
        return Result.success(testVo);
    }
    
}

       注:要想让我们的验证有效就必须的在我们的对象前用@Valid注解标明,不然不生效哦!想接收提示也得加入BindingResult类!

测试:

   我们先不加入参数看看效果,分别访问:localhost:8080/test,localhost:8080/test1

我们可以看到,提示信息就出来啦。当然具体要提示几个,看你的需求啦!

 

源码地址:https://gitee.com/xu0123/springboot2

上一篇:springboot(十三)全局异常处理

下一篇:springboot(十五)redis实现分布式session共享

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值