栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

spring boot后端参数校验

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

spring boot后端参数校验

spring boot后端参数校验

备注:shigendemo 2022年06月16日
原文链接:点击阅读原文

1.问题情境

2021年的9月我开始书写我的demo项目,并在老师的帮助下于9月28日成功的上线项目。国庆之后发现系统中出现了非法的数据,如:用户的头像不是一个图片名称…我自认为自己的前端写的没啥问题,只有在表单的数据验证之后才会往后端提交数据。

2.如何发现

我在操场奔跑的时候忽然想到了暑假在一家公司实习的时候做了接口测试,只用获得token(前后端的身份认证)即可调用接口传参数,我记得当初写的一个脚本帮助大数据那边的调用系统接口获得数据:

那么这次我遇到了高手,他懂得如何的接口测试。我的前端做了一次参数的校验,但是后端照样需要一次数据校验才能保证到数据库的数据是合法的、安全的。

3.解决办法

采用了javax和hibernate提供的注解解决,详见【4.学习总结】

4.学习总结

数据的验证必须前端和后端都要处理,保证数据的合法性和安全性。
使用如下:

@Data
@Accessors(chain = true)
public class User {

  
  @NotNull(message = "修改时必须指定id")
  private Long id;
  
  @NotBlank(message = "用户名必须提交")
  private String username
 } 
4.1 自定义异常兜底

主要是用来处理数据验证异常和自定义也无异常一级兜底的异常

@RestControllerAdvice
@Slf4j
public class WebExceptionHandler extends RuntimeException {

  
  @ExceptionHandler(MethodArgumentNotValidException.class)
  @ResponseBody
  public Result validationErrorHandler(MethodArgumentNotValidException ex) {
    String message = ex.getBindingResult().getAllErrors().stream()
        .map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining());
    return Result.err(message);
  }

  
  @ExceptionHandler(ValidationException.class)
  @ResponseBody
  public Result validationErrorHandler(BindException ex) {
    String message = ex.getBindingResult().getAllErrors().stream()
        .map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining());
    log.error(message);
    return Result.err(message);
  }

  
  @ExceptionHandler(ConstraintViolationException.class)
  @ResponseBody
  public Result validationErrorHandler(ConstraintViolationException ex) {
    String message = ex.getConstraintViolations().stream().map(ConstraintViolation::getMessage)
        .collect(Collectors.joining());
    return Result.err(message);
  }

  
  @ExceptionHandler(Exception.class)
  public Result defaultHandler(Exception e) {
    log.error("exception: {}", ExceptionUtil.stacktraceToString(e));
    return Result.err("服务器错误");
  }
}
4.2 自定义验证组
  • 添加自定义的组接口
public interface AddGroup {

}
  • 注解的使用
@Data
@Accessors(chain = true)
public class User {

  
  @Null(message = "新增时不能指定id", groups = {AddGroup.class})
  @NotNull(message = "修改时必须指定id", groups = {UpdateGroup.class})
  private Long id;
  
  @NotBlank(message = "用户名必须提交", groups = {AddGroup.class, UpdateGroup.class})
  private String username;
}  
  • 用在请求体参数的验证(只针对特定的组进行数据的验证)
4.3 自定义验证注解
  • 自定义注解

可参照javax和 hibernate提供的注解

@Documented
@Constraint(validatedBy = {ListValueConstraintValidator.class})
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ListValue {

  String message() default "{com.shigen.demo.annation.valid.ListValue.message}";

  Class[] groups() default {};

  Class[] payload() default {};

  int[] values() default {};
}
  • 自定义验证器
public class ListValueConstraintValidator implements ConstraintValidator {

  private Set set = new HashSet<>();

  
  @Override
  public void initialize(ListValue constraintAnnotation) {
    int[] values = constraintAnnotation.values();
    for (int value : values) {
      set.add(value);
    }
  }

  
  @Override
  public boolean isValid(Integer integer, ConstraintValidatorContext constraintValidatorContext) {
    return set.contains(integer);
  }
}
  • 自定义message

  • 使用

  
  @ListValue(values = {0, 1}, groups = AddGroup.class)
  private Integer flag;
  • 效果
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/981649.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号