上文我们讨论了spring-boot如何去获取前端传递过来的参数,那传递过来总不能直接使用,需要对这些参数进行校验,符合程序的要求才会进行下一步的处理,所以本篇文章我们主要讨论spring-boot中如何进行参数校验。

lombok使用介绍

在介绍参数校验之前,先来了解一下lombok的使用,因为在接下来的实例中或有不少的对象创建,但是又不想写那么多的getter和setter,所以先介绍一下这个很强大的工具的使用。

Lombok 是一个可以通过简单的注解形式来帮助我们简化消除一些必须有但显得很臃肿的Java代码的工具,通过使用对应的注解,可以在编译源码的时候生成对应的方法。

添加maven依赖

在pom文件中添加如下内容:

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</dependency>

基础注解

@Getter给类增加get方法

@Setter给类增加set方法

@Builder给类增加构建者模式

@AllArgsConstructor给类增加全参构造方法

@NoArgsConstructor给类增加无参数构造方法

@RequiredArgsConstructor按照必填属性增加构造方法

@NonNull变量值不能为空

这里只简单列一下常用注解的含义,具体的使用方式在参数校验的实例中体现。

实战

上篇文章中我们用BannerCreateDto这个对象了来接收前端传递的参数,那时是手动添加的get和set方法,这里我们用lombok注解来简化掉之前的样板代码:

@Setter
@Getter
public class BannerCreateDto {
private String name;
private Integer pos;
}

接口的定义还是和之前一样。不同做任何修改:

@PostMapping(value = "/create")
public Map<String, Object> createBanner(@RequestBody BannerCreateDto dto){
Map<String, Object> res = new HashMap<>();
res.put("id", 10000);
res.put("name", dto.getName());
res.put("pos", dto.getPos());
return res;
}

重新运行程序,访问接口

还是和之前一样,能够请求成功并正常的返回数据。

一般情况下,我们会针对返回的数据,来单独定义对象来进行描述,这里我们也定义一个

@Builder
@Getter
public class BannerResponseDto {
private int id;
private String name;
private Integer pos;
}

这里用到了@Builder、@Getter,在接口中构造对象并返回:

@PostMapping(value = "/create")
public BannerResponseDto createBanner(@RequestBody BannerCreateDto dto){ return BannerResponseDto.builder()
.id(500)
.name(dto.getName())
.pos(dto.getPos())
.build();
}

可以看到lombok的@Builder注解,能够让类通过构建者模式去创建对象,省去了大量的set代码,而且可读性也很好。

访问接口,看看数据返回的时候正常:

与之前是一样的,能够正常返回数据,那接下来我们就正式看一下,spring-boot如何进行参数校验了。

参数校验

参数校验就是说对前端传过来的数据进行合理性校验,看他能否满足我们的业务规则,那这些对参数进行校验的代码是该放在那里呢,是在Controller里还是说单独存放,又获取采用其他什么方式呢?

参数校验该怎么做

首先要明确的一点,在Controller,不应该有大量逻辑判断的代码,为什么呢,我们可想想当参数较多的时候,对每个参数进行合理性校验的话,那代码量该有多少,那就会严重污染Controller,导致维护起来是很艰难的,所以应该要有一个合理的机制能把校验的代码抽离出来,从而保证Controller的简洁性。

在java的世界里有这么个概念叫做 JSR,是Java Specification Requests的首字母缩写,是编程语言Java规范请求或者说是Java语言的说明书,既然是说明书那就一定有各个版本,在JSR-303版本中,提出了Bean Validation的验证规范,目前主要有两个两个框架实现了Bean Validation规范,一个事自带的javax.validation.api和hibernate-validator框架,而hibernate-validator框架应用的更加广泛一点。

那我们就用这种Bean Validation这种验证框架进行参数的验证

实战

@RestController
@Validated
public class BannerController { @GetMapping("/v3/banner")
public Map<String, Object> getBannerDetailV2(@RequestParam Integer id, @RequestParam @Max(10) Integer pos){
Map<String, Object> body = new HashMap<>();
body.put("id", id);
body.put("pos", pos);
return body;
}
}

上面代码中,@Max(10)注解来验证输入参数的pos,限制其输入参数最大值为10,运行程序我们来测试一下:

访问接口http://localhost:8081/v3/banner?id=12&pos=33后,看到我们控制台的输出提示输入不能超过10,这里的这个message不是我写的哈,这是java国际化后的效果能够根据你所在地区决定显示什么语言。

当然这里我们也可以自定义错误的message:

@GetMapping("/v3/banner")
public Map<String, Object> getBannerDetailV2(@RequestParam Integer id,
@RequestParam @Max(value = 10, message = "超过10了,赶紧看看哇") Integer pos){
Map<String, Object> body = new HashMap<>();
body.put("id", id);
body.put("pos", pos);
return body;
}

还是上面的请求路径,看看控制台输出:

可以看到控制台输出了我们自定义的内容。这里有一点要注意,要想使得校验生效,比如在Controller上方打上@Validated注解,至于为什么我们后面分解

上面的验证都是比较基础的数据类型,但是如果现在要有验证更加复杂一点的java对象呢,又该如何操作,那接下来我们再看看这部分的内容。

java对象进行验证

单个对象

还是用上面的BannerResponseDto来进行演示

import org.hibernate.validator.constraints.Length;
@Setter
@Getter
public class BannerCreateDto {
@Length(min = 2, max = 4, message = "banner名称必须是2-10个字符")
private String name;
private Integer pos;
}

对于这些基础类型的成员变量仍然使用这些基础注解进行校验定义,上面我们使用了 @Length注解来定义banner名称的字符长度范围,并定义发生错误时提示的message,这里还需要在Controller里额外的处理一下:

@PostMapping("/v3/banner/create")
public BannerResponseDto createBanner(@RequestBody @Validated BannerCreateDto dto){ return BannerResponseDto.builder()
.id(500)
.name(dto.getName())
.pos(dto.getPos())
.build();
}

@Validated BannerCreateDto这里必须要加@Validated注解,否则无法触发校验机制。

嵌套

如果某个类的成员变量也是一个自定义对象,那校验该是什么样的呢,下面我们来看一下。

先定义一个新的对象,用来接收banner到的素材信息

@Getter
@Setter
public class MaterialDto {
@Length(min = 2, max = 5, message = "素材的名称长度范围必须在2-5之内")
private String name;
}

然后banner对象增加一个成员变量

@Setter
@Getter
public class BannerCreateDto {
@Length(min = 2, max = 4, message = "banner名称必须是2-10个字符")
private String name;
private Integer pos; @Valid
private MaterialDto materialDto;
}

这里有一点,要想使得这种级联的关系能够触发校验机制,必须 @Valid注解进行标记,我们来请求一下url看看效果

可以看到校验没通过,再看看控制台输出内容:

输出了我们定义的错误信息。

总结

本篇文章主要介绍了里面lombok的使用,以及校验规范介绍和校验框架基本注解的使用,还有自定义对象校验,下篇文章我们将通过自定义注解来实现更加个性化的校验规则,敬请期待。

欢迎大家去 我的博客 瞅瞅,里面有更多关于测试实战的内容哦!!

测试开发专题:如何在spring-boot中进行参数校验的更多相关文章

  1. 如何在 Spring/Spring Boot 中做参数校验?你需要了解的都在这里!

    本文为作者原创,如需转载请在文首著名地址,公众号转载请申请开白. springboot-guide : 适合新手入门以及有经验的开发人员查阅的 Spring Boot 教程(业余时间维护中,欢迎一起维 ...

  2. 如何在 Spring/Spring Boot 中做参数校验

    数据的校验的重要性就不用说了,即使在前端对数据进行校验的情况下,我们还是要对传入后端的数据再进行一遍校验,避免用户绕过浏览器直接通过一些 HTTP 工具直接向后端请求一些违法数据. 本文结合自己在项目 ...

  3. 如何在Spring boot中修改默认端口

    文章目录 介绍 使用Property文件 在程序中指定 使用命令行参数 值生效的顺序 如何在Spring boot中修改默认端口 介绍 Spring boot为应用程序提供了很多属性的默认值.但是有时 ...

  4. 如何在Spring Boot中使用Cookies

    一. 导读 本文大纲 读取HTTP Cookie 设置HTTP Cookie 读取所有Cookie[] 为Cookie设置过期时间 Https与Cookie HttpOnly Cookie 删除Coo ...

  5. 如何在Spring Boot 中动态设定与执行定时任务

    本篇文章的目的是记录并实现在Spring Boot中,动态设定与执行定时任务. 我的开发项目是 Maven 项目,所以首先需要在 pom.xml 文件中加入相关的依赖.依赖代码如下所示: <de ...

  6. spring boot 中接口参数为枚举时的反序列化配置(总结)

    步骤 如果是 GET 请求中需要反序列化枚举值(即 url 中的参数[querystring]),确保以下两点 1.1. 重写 StringToEnumConverterFactory 1.2. 配置 ...

  7. 如何在spring boot中从控制器返回一个html页面?

    项目截图 解决方法 我之前用的@RestController注解,而@RestController这个控制器返回数据而不是视图,改成@Controller 就好了(以下是修改后的) @Controll ...

  8. 如何在 Spring Boot 中禁用 Actuator 端点安全性?

    默认情况下,所有敏感的 HTTP 端点都是安全的,只有具有 ACTUATOR 角色的用户才能访问它们.安全性是使用标准的 HttpServletRequest.isUserInRole 方法实施的. ...

  9. Spring Boot中的测试

    文章目录 简介 添加maven依赖 Repository测试 Service测试 测试Controller @SpringBootTest的集成测试 Spring Boot中的测试 简介 本篇文章我们 ...

随机推荐

  1. [YII2] COOKIE的操作使用

    PHPcookie的设置 setcookie('username',$data['username'],time()+3600*24*7); YII2cookie的设置 $cookies = Yii: ...

  2. Des对称可逆加密

    /// <summary> /// DES AES Blowfish ///  对称加密算法的优点是速度快, ///  缺点是密钥管理不方便,要求共享密钥. /// 可逆对称加密  密钥长 ...

  3. 使用JAVA API编程实现简易Habse操作

    使用JAVA API编程实现下面内容: 1.创建<王者荣耀>游戏玩家信息表gamer,包含列族personalInfo(个人信息).recordInfo(战绩信息).assetsInfo( ...

  4. ES6系列-什么是ES6?新手应该怎么理解

    ECMAScript 是什么 很多初学者都很困惑,ECMAScript是什么?它跟JavaScript有什么关系? 大家注意到了吗?从题目中我们就可以看出来了,ECMAScript是JavaScrip ...

  5. tensor求和( tensor.sum())

    1. torch.sum(input, dim, out=None) 参数说明: input:输入的tensor矩阵. dim:求和的方向.若input为2维tensor矩阵,dim=0,对列求和:d ...

  6. sqlilab11-14

    less11 抓包 ' " 实验发现'构成闭合,存在注入点 less-12 a,b都有注入点,b比较好判断闭合 less13 less14

  7. 安卓微信浏览器中window.location.href失效的问题

    最近接手一微信项目,测试功能时,发现跳转在android手机上不动了.iso系统可以正常跳转的.解决方法: window.location.href = url + '?v=' + (new Date ...

  8. ELK6.3版本安装部署

    一.Elasticsearch 安装 1.部署系统以及环境准备 cat /etc/redhat-release CentOS Linux release 7.4.1708 (Core) uname - ...

  9. Scala教程之:深入理解协变和逆变

    文章目录 函数的参数和返回值 可变类型的变异 在之前的文章中我们简单的介绍过scala中的协变和逆变,我们使用+ 来表示协变类型:使用-表示逆变类型:非转化类型不需要添加标记. 假如我们定义一个cla ...

  10. 联想在S规则债券市场完成了里程碑式的新债券发行

    腾讯科技讯,香港,2020 年 4 月 24 日-联想集团(HKSE:992)(ADR:LNVGY)今日宣布,在S规则债券市场上成功发行了里程碑式的 6.5 亿美元债券. 这些债券吸引了全球大量固定收 ...