前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【开发日记】SpringBoot做参数校验

【开发日记】SpringBoot做参数校验

作者头像
全栈开发日记
发布2022-12-07 11:23:13
4160
发布2022-12-07 11:23:13
举报
文章被收录于专栏:全栈开发日记

目录:

1、前言 2、加入依赖 3、创建VO实体类 4、创建接口 5、创建全局异常处理器 6、添加效验注解 7、分组 8、优化参数效验 9、@Validated或@Valid区别 10、效果

1、前言

这里的参数效验指的是在Web接口中接收参数时对参数的合法性进行效验;正常情况的做法是在接收到参数时,在方法体中对参数进行核验;这样做的代码整洁性太差、代码侵入性太强;这里推荐一个利用SpringBoot中推荐的注解方式进行参数效验。

2、加入依赖

代码语言:javascript
复制
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

3、创建VO实体类

代码语言:javascript
复制
@Data
public class Parameter implements Serializable {
    String scene;
    ArrayList<Point> path;
    Double speed;
    Integer state;
    JSONObject inputValues;
}

这个类用于接收客户端的请求参数;使用实体类接收参数时实体类需要有Getter、Setter方法,我这里用到Lombok下的@Data注解自动生成这些方法,所以就没有加Getter、Setter方法。

4、创建接口

代码语言:javascript
复制
@PostMapping("")
public RequestResult app(@Validated @RequestBody Parameter parameter) {
    RequestResult requestResult = new RequestResult();
    requestResult.appendData("result", app.start(parameter));
    return requestResult;
}

需要在接收参数的实体类上加入@Validated@Valid注解,否则参数效验不会生效,这两个注解的区别后面说明。

相信能看到这里的小伙伴使用SpringMVC创建接口应该问题不大,所以这里就不展示接口类了,重点在使用实体类接收参数时如何使用注解对参数进行效验。

5、创建全局异常处理器

代码语言:javascript
复制
@RestControllerAdvice
public class ParameterExceptionHandler {
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public RequestResult handleMethodArgumentNotValidException(MethodArgumentNotValidException e, HttpServletRequest request) {
        RequestResult requestResult = new RequestResult();
        requestResult.setCode(400);
        requestResult.setMessage(Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage());
        requestResult.appendData("url",request.getRequestURI());
        return requestResult;
    }
}

当参数效验失败,会抛出MethodArgumentNotValidException异常,这个类的作用就是捕获这个异常,然后将这个异常翻译成用户能看懂的样子。

6、添加效验注解

用于效验的注解可用于方法参数中,也可以用于实体类中;如果是实体类中使用的话,需要在方法参数实体类前加入@Validated注解;如果实体类中有嵌套其他的实体类,也需要参数效验,则使用@Valid注解标识,@Validated@Valid注解区别会在后面说明。

@NotEmpty

表示不能为null,也不能为空字符串,当类型为集合时集合不能为空,但是字符串可以是" "(注意引号之间有一个空格)。

代码语言:javascript
复制
@NotEmpty(message = "季节不能为空")
String scene;

@NotNull

表示不可以为null,但可以是空字符串;

代码语言:javascript
复制
@NotNull(message = "季节不能为空")
String scene;

@NotBlank

用于字符串,表示不能为null,也不能为空字符串,空格字符串也不行。

@Length

用于字符串上,限制字符串长度。

代码语言:javascript
复制
@Length(max = 1,min = 1,message = "用于表示季节的字符为A(夏季)、B(冬季)")
String scene;

@Size

用于字符串、数组和集合上,也是限制长度。

代码语言:javascript
复制
@Size(min = 2, message = "表示路线的坐标点应该不少于2个")
ArrayList<Point> path;

@Min@Max

表示最小值和最大值,用于字符串或数值上,如果是字符串则转换为BigDecimal再进行比较。

代码语言:javascript
复制
@Min(value = 10,message = "速度应大于等于10千米每小时")
@Max(value = 20,message = "速度应小于等于20千米每小时")
Double speed;

@Range

表示取值范围,与@Min@Max组合使用类似。

代码语言:javascript
复制
@Range(min = 1, max = 3, message = "状态应使用1-正常、2-加速、3-慢速")
Integer state;

@Email

效验邮箱格式。

代码语言:javascript
复制
@Email(message = "格式不符合规范")
String mail;

@URL

表示该参数值必须是一个URL。

代码语言:javascript
复制
@URL(message = "格式不符合规范")
String url;

@Pattern

表示该参数值必须符合这个正则表达式。

代码语言:javascript
复制
@Pattern(regexp = "^[A-Z]+$",message = "格式不符合规范")
String scene;

7、分组

使用@Validated注解可设置参数效验分组;示例如下:

① 创建两个分组

代码语言:javascript
复制
public interface Autumn {
}

public interface Spring {
}

② 控制器接口

表示当前是Spring分组;

代码语言:javascript
复制
@PostMapping("")
public RequestResult app(@Validated({Spring.class}) @RequestBody Parameter parameter) {
    RequestResult requestResult = new RequestResult();
    requestResult.appendData("result", app.start(parameter));
    return requestResult;
}

③标识参数分组

表示只有当前分组是Autumn时才会生效。

代码语言:javascript
复制
@Size(min = 2, message = "表示路线的坐标点应该不少于2个",groups = {Autumn.class})
ArrayList<Point> path;

8、优化参数效验

如上的效验过程中,会效验所有的参数,然后把不合格的全部返回给客户端。

通过如下配置可以做到当有一个参数效验不通过时即返回,不用效验所有参数,增加效率。

代码语言:javascript
复制
@Configuration
public class AppConfig {
    @Bean
    public Validator validator(AutowireCapableBeanFactory beanFactory) {
        try (ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
                .configure().failFast(true)
                .constraintValidatorFactory(new SpringConstraintValidatorFactory(beanFactory))
                .buildValidatorFactory()) {
            return validatorFactory.getValidator();
        }
    }
}

9、@Validated@Valid区别

①用法

@Validated注解可被用于方法参数上;无法用于成员属性上;

@Valid注解可被用于方法构造方法、参数和成员属性上;

②分组

@Validated注解提供分组用法,可根据分组情况提供不同的参数效验规则;

@Valid注解不提供;

10、效果

参数效验未通过后的效果如下:

代码语言:javascript
复制
{
    "code": 400,
    "message": "表示路线的坐标点应该不少于2个",
    "data": {
        "url": "/test"
    }
}

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-11-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 全栈开发日记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、前言
  • 2、加入依赖
  • 3、创建VO实体类
  • 4、创建接口
  • 5、创建全局异常处理器
  • 6、添加效验注解
    • ①@NotEmpty
      • ②@NotNull
        • ③@NotBlank
          • ④@Length
            • ⑤@Size
              • ⑥@Min和@Max
                • ⑦@Range
                  • ⑧@Email
                    • ⑨@URL
                      • ⑩@Pattern
                      • 7、分组
                        • ① 创建两个分组
                          • ② 控制器接口
                            • ③标识参数分组
                            • 8、优化参数效验
                            • 9、@Validated或@Valid区别
                              • ①用法
                                • ②分组
                                • 10、效果
                                领券
                                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档