springboot(十四)参数校验

x33g5p2x  于2021-12-17 转载在 其他  
字(4.5k)|赞(0)|评价(0)|浏览(338)

前言:

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

    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

相关文章