springboot(十四)参数校验

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

前言:

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

    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

  1. <dependencies>
  2. <!--web-->
  3. <dependency>
  4. <groupId>org.springframework.boot</groupId>
  5. <artifactId>spring-boot-starter-web</artifactId>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.springframework.boot</groupId>
  9. <artifactId>spring-boot-starter-test</artifactId>
  10. <scope>test</scope>
  11. </dependency>
  12. <!--lombok-->
  13. <dependency>
  14. <groupId>org.projectlombok</groupId>
  15. <artifactId>lombok</artifactId>
  16. <version>1.16.22</version>
  17. </dependency>
  18. </dependencies>

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

            

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

  1. @Data
  2. public class CodeMsg {
  3. private int code;
  4. private String msg;
  5. //错码定义误
  6. public static CodeMsg SUCCESS = new CodeMsg(0, "success");
  7. public static CodeMsg SERVER_ERROR = new CodeMsg(50000, "服务端异常");
  8. public static CodeMsg BIND_ERROR = new CodeMsg(50001, "参数校验异常:%s");
  9. public static CodeMsg REQUEST_ILLEGAL = new CodeMsg(50002, "请求非法");
  10. private CodeMsg( int code,String msg ) {
  11. this.code = code;
  12. this.msg = msg;
  13. }
  14. public CodeMsg fillArgs(Object... args) {
  15. int code = this.code;
  16. String message = String.format(this.msg, args);
  17. return new CodeMsg(code, message);
  18. }
  19. }

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

  1. @Data
  2. public class Result<T> {
  3. //提示码
  4. private int code;
  5. //消息
  6. private String msg;
  7. //返回提示
  8. private T data;
  9. /**
  10. * 成功时候的调用
  11. * */
  12. public static <T> Result<T> success(T data){
  13. return new Result<T>(data);
  14. }
  15. /**
  16. * 失败时候的调用
  17. * */
  18. public static <T> Result<T> error(CodeMsg codeMsg){
  19. return new Result<T>(codeMsg);
  20. }
  21. private Result(T data) {
  22. this.data = data;
  23. }
  24. private Result(int code, String msg) {
  25. this.code = code;
  26. this.msg = msg;
  27. }
  28. private Result(CodeMsg codeMsg) {
  29. if(codeMsg != null) {
  30. this.code = codeMsg.getCode();
  31. this.msg = codeMsg.getMsg();
  32. }
  33. }
  34. }

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

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

  1. @Data
  2. public class TestVo {
  3. @NotBlank(message = "姓名不能为空")
  4. private String name;
  5. @NotNull(message = "年龄必填")
  6. @Max(value = 20,message = "年龄必须小于20")
  7. @Min(value = 0,message = "年龄必须大于0")
  8. private Integer age;
  9. }

编写验证工具类:BindingResultUtil.java

  1. public class BindingResultUtil {
  2. /**
  3. * 多个参数验证提示
  4. * @param bindingResult
  5. * @return
  6. */
  7. public static Result bindingResults(BindingResult bindingResult){
  8. Map<String, String> errorMsg = new HashMap<String, String>();
  9. List<FieldError> fieldErrors = bindingResult.getFieldErrors();
  10. for(FieldError fieldError:fieldErrors){
  11. errorMsg.put(fieldError.getField(), fieldError.getDefaultMessage());
  12. }
  13. return Result.error(CodeMsg.BIND_ERROR.fillArgs(errorMsg));
  14. }
  15. /**
  16. * 单个参数验证提示
  17. * @param bindingResult
  18. * @return
  19. */
  20. public static Result bindingResult(BindingResult bindingResult){
  21. return Result.error(CodeMsg.BIND_ERROR.fillArgs(bindingResult.getFieldError().getDefaultMessage()));
  22. }
  23. }

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

编写测试类TestController.java

  1. @RestController
  2. public class TestController {
  3. private final Logger logger= LoggerFactory.getLogger(TestController.class);
  4. /**
  5. * 返回所有不满足验证参数的提示
  6. * @param testVo
  7. * @param bindingResult
  8. * @return
  9. */
  10. @GetMapping("/test")
  11. public Result<TestVo> test(@Valid TestVo testVo , BindingResult bindingResult) {
  12. //判断是否有错,是否有不满足校验的参数
  13. if (bindingResult.hasErrors()) {
  14. //返回多个提示信息
  15. return BindingResultUtil.bindingResults(bindingResult);
  16. }
  17. logger.info("testVo={}"+testVo.toString());
  18. return Result.success(testVo);
  19. }
  20. /**
  21. * 只返回一个不满足验证参数的提示
  22. * @param testVo
  23. * @param bindingResult
  24. * @return
  25. */
  26. @GetMapping("/test1")
  27. public Result<TestVo> test1(@Valid TestVo testVo ,BindingResult bindingResult) {
  28. //判断是否有错,是否有不满足校验的参数
  29. if (bindingResult.hasErrors()) {
  30. //返回单个提示信息
  31. return BindingResultUtil.bindingResult(bindingResult);
  32. }
  33. logger.info("testVo={}"+testVo.toString());
  34. return Result.success(testVo);
  35. }
  36. }

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

测试:

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

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

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

相关文章