您当前的位置:首页 > 电脑百科 > 程序开发 > 框架

如何在 Spring Boot 中验证 JSON 请求正文

时间:2022-10-31 15:49:47  来源:今日头条  作者:qaseven

我们将研究 request-validator 库,它能够将用户输入与预定义的一组规则(如 required、max、min、emAIl 等)进行比较。

我们有时会遇到由于用户提供的输入长于数据库列大小甚至不存在的 ENUM 值而导致的服务器错误。不信任用户输入是一种流行的陈词滥调,如果实施,将节省大量时间和资源。
这就是为什么在本文中,我们将研究request-validator库,它能够将用户输入与一组预定义的规则进行比较,并在有错误时返回错误。
依赖安装
为了让我们使用request-validator,我们需要将它添加到我们项目的pom.xml中:
清单 2.1 pom.xml

<dependency>
<groupId>com.smattme</groupId>
<artifactId>request-validator</artifactId>
<version>0.0.2</version>
</dependency>


最新版本的依赖项在Maven 中心可用。
验证 JSON 请求正文
鉴于我们有一个简单的登录端点,需要有效的电子邮件和密码,并且作为一名优秀的工程师,我们希望确保用户发送两个字段并且电子邮件是有效的。
我们可以使用request-validator 库轻松实现这一点。对于电子邮件 输入字段,我们希望用户提供一个非空字段和一个有效的电子邮件地址,而对于密码字段,我们只希望用户提供一个非空值:
清单 3.1 LoginController.JAVA
@RestController
public class LoginController {
@PostMApping("/auth/login")
public ResponseEntity<GenericResponse> login(@RequestBody LoginRequest request) {
Map<String, String> rules = new HashMap<>();
rules.put("email", "required|email");
rules.put("password", "required");
List<String> errors = RequestValidator.validate(request, rules);
if (!errors.isEmpty()) {
GenericResponse genericResponse = new GenericResponse();
genericResponse.setStatus(false);
genericResponse.setCode(
HttpStatus.BAD_REQUEST.value());
genericResponse.setErrors(errors);

genericResponse.setMessage("Missing required parameter(s)");
return ResponseEntity.badRequest().body(genericResponse);
}
//otherwise all is well, process the request
//loginService.login()
return ResponseEntity.ok(
GenericResponse.generic200Responseobj("Login successful"));
}
}
从上面的清单 3.1 中,我们使用Map<String, String>来存储每个预期请求字段的规则。映射的键是 API 用户应提供的字段名称,而值包含验证规则。
然后我们调用RequestValidator.validate()方法来检查传入的请求对象是否符合定义的规则。该方法返回一个List<String>,如果存在违规,它将包含所有错误消息。
该库的一大优势是它为每个规则返回一个单独的描述性错误消息,并在一次调用中检查所有规则。
因为RequestValidator.validate()需要Object数据类型,所以请求对象可以是Map、POJO 甚至是 JSON String。
如果 API 用户提供了无效的请求正文,他们将收到 400 错误请求,其中包含所有数据违规的详细列表:
清单 3.2 curl请求/响应

Request:
curl --location --request POST 'http://localhost:8080/auth/login'
--header 'Content-Type: application/json'
--data-raw '{
"email": "john"
}'
Response:
{
"status": false,
"message": "Missing required parameter(s)",
"errors": [
"password is required",
"email supplied is invalid"
],
"code": 400
}


但是,正如预期的那样,有效的请求正文将返回成功:
清单 3.3 curl请求/响应

Request:
curl --location --request POST 'http://localhost:8080/auth/login'
--header 'Content-Type: application/json'
--data-raw '{
"email": "john@example.com",
"password": "changeit"
}'
Response:
{
"status": true,
"message": "Login successful",
"code": 200
}


请注意,返回的List<String>错误可以以您和您的团队选择的任何方式用作您的响应的一部分。它不限于本文中演示的响应格式。
本文末尾提供了完整的源代码,它将帮助您更好地理解本教程中的响应格式是如何格式化的。
请求验证器库允许我们使用竖线 (|) 字符作为分隔符将一个或多个规则组合在一起。从上面的清单 3.1 中,我们使用|将required和email规则组合在一起。.
唯一的例外是在将正则表达式规则与其他规则一起使用时。它应该是最后一条规则,并且应该用双竖线字符分隔,如 || . 这是为了适应正则表达式模式中管道字符的潜在存在:
清单 3.3 正则表达式模式:

Map<String, String> rules = new HashMap<>();
rules.put("dob", "required||regex:[0-9]{2}-[0-9]{2}-[0-9]{4}");


完整的规则列表可在此处获得。
定义自定义规则
假设我们要添加一个默认不在库中的自定义验证规则,我们可以通过继承 RequestValidator 类并实现RuleValidator接口轻松实现它。
鉴于我们需要添加一条规则以确保用户提供的值以custom_ 开头,首先,我们需要创建一个PrefixRuleValidator 类,该类将实现RuleValidator接口并执行自定义逻辑:
清单 4.1 PrefixRuleValidator.java

public class PrefixRuleValidator implements RuleValidator {


我们需要的下一个组件是一个扩展RequestValidator 的类。 我们将调用这个CustomRequestValidator,而不是库的RequestValidator,来进行我们的检查:
清单 4.2
CustomRequestValidator.java
public class CustomRequestValidator extends RequestValidator {
static {
ruleValidatorMap.put("customprefix", PrefixRuleValidator.class);
}
public static List<String> validate(Object target, Map<String, String> rules) {
String jsonRequest =
convertObjectRequestToJsonString(target);
return validate(jsonRequest, rules, ruleValidatorMap);
}
}
CustomRequestValidator的结构很简单,我们将PrefixRuleValidator类静态添加到父级的ruleValidatorMap中。然后我们继续创建父级的validate()方法的副本,这将有效地使我们的规则与其他默认规则一起可用。
最后,让我们在控制器中使用我们的自定义规则:
清单 4.3
CustomPrefixController.java
@RestController
public class CustomPrefixController {
@PostMapping("/custom")
public ResponseEntity<GenericResponse> formCustomPrefix(@RequestBody Map<String, Object> request) {
Map<String, String> rules = Collections.singletonMap("objectType", "customprefix");
List<String> errors =
CustomRequestValidator.validate(request, rules);
if(!errors.isEmpty()) {
GenericResponse genericResponse = new GenericResponse();
genericResponse.setStatus(false);
genericResponse.setCode(
HttpStatus.BAD_REQUEST.value());
genericResponse.setErrors(errors);

genericResponse.setMessage("Missing required parameter(s)");
return ResponseEntity.badRequest().body(genericResponse);
}
return ResponseEntity.ok(
GenericResponse.generic200ResponseObj("Operation successful"));
}
}
发布有效请求将返回 200 OK:
清单 4.4 Curl请求/响应

Request:
curl --location --request POST 'http://localhost:8080/custom'
--header 'Content-Type: application/json'
--data-raw '{
"objectType": "custom_john"
}'
Response:
{
"status": true,
"message": "Operation successful",
"code": 200
}


另一方面,发布无效请求将返回错误消息,如代码清单 4.1 PrefixRuleValidator.java 所示:
清单 4.5 Curl请求/响应

Request:
curl --location --request POST 'http://localhost:8080/custom'
--header 'Content-Type: application/json'
--data-raw '{
"objectType": "john"
}'
Response:
{
"status": false,
"message": "Missing required parameter(s)",
"errors": [
"objectType should start with custom_"
],
"code": 400
}


结论
在本文中,我们了解了如何轻松验证 JSON 请求正文并确保 API 使用者发送我们期望的数据以及实际示例。完整的源代码可在Github
https://github.com/SeunMatt/smattme-tutorials/tree/master/spring-boot-request-validator上获得。快乐编码。



Tags:Spring Boot   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
Spring Boot2.0深度实践 核心原理拆解+源码分析
Spring Boot2.0深度实践:核心原理拆解与源码分析一、引言Spring Boot是一个基于Java的轻量级框架,它简化了Spring应用程序的创建过程,使得开发者能够快速搭建一个可运行的应用...【详细内容】
2024-01-15  Search: Spring Boot  点击:(96)  评论:(0)  加入收藏
Spring Boot 3.0是什么?
Spring Boot 3.0是一款基于Java的开源框架,用于简化Spring应用程序的构建和开发过程。与之前的版本相比,Spring Boot 3.0在多个方面进行了改进和增强,使其更加易用、高效和灵活...【详细内容】
2024-01-11  Search: Spring Boot  点击:(133)  评论:(0)  加入收藏
GraalVM与Spring Boot 3.0:加速应用性能的完美融合
在2023年,SpringBoot3.0的发布标志着Spring框架对GraalVM的全面支持,这一支持是对Spring技术栈的重要补充。GraalVM是一个高性能的多语言虚拟机,它提供了Ahead-of-Time(AOT)编...【详细内容】
2024-01-11  Search: Spring Boot  点击:(124)  评论:(0)  加入收藏
Spring Boot虚拟线程的性能还不如Webflux?
早上看到一篇关于Spring Boot虚拟线程和Webflux性能对比的文章,觉得还不错。内容较长,抓重点给大家介绍一下这篇文章的核心内容,方便大家快速阅读。测试场景作者采用了一个尽可...【详细内容】
2024-01-10  Search: Spring Boot  点击:(119)  评论:(0)  加入收藏
Spring Boot Starter的原理
Spring Boot Starter 是 Spring Boot 框架的特性之一,用于简化应用程序的依赖管理和配置。1. 概述: - Spring Boot Starter 是一种包含了一组特定功能和依赖关系的依赖项,旨在...【详细内容】
2024-01-05  Search: Spring Boot  点击:(94)  评论:(0)  加入收藏
Spring Boot 统一响应体处理器详解
在Spring Boot应用中,统一处理响应体是一项非常重要的任务,它可以让我们更方便地统一规范API的返回格式。今天,我们将深入探讨一个优雅的解决方案&mdash;&mdash;使用ResultHand...【详细内容】
2023-11-30  Search: Spring Boot  点击:(150)  评论:(0)  加入收藏
Spring Boot 调优内嵌 Tomcat 的三种方法
在 Spring Boot 中优化 Apache Tomcat 有三种方式,以便实现更好的性能和资源利用率。 线程池(连接器和执行器)设置 使用 NIO 或 APR 连接器 JVM优化线程池设置在 Spring Boot...【详细内容】
2023-11-23  Search: Spring Boot  点击:(228)  评论:(0)  加入收藏
一文搞懂Spring Boot控制器的关键要点
Spring Boot 应用程序中的控制器扮演着重要角色,负责处理传入的 HTTP 请求并确定应发送的适当响应。本文深入介绍 Spring Boot 中的控制器,包括如何创建控制器、处理各种类型...【详细内容】
2023-11-20  Search: Spring Boot  点击:(151)  评论:(0)  加入收藏
Spring Boot中实现订单30分钟自动取消的策略思路及源代码
方式一:使用定时任务 首先,创建一个定时任务,比如每30分钟执行一次检查订单是否需要取消的逻辑。 在订单生成的时候,保存一条记录到数据库,标记订单的状态为"待处理"。 在定时任...【详细内容】
2023-11-20  Search: Spring Boot  点击:(221)  评论:(0)  加入收藏
Spring Boot + Vue3 前后端分离 实战wiki知识库系统
下栽の地止:https://www.itwangzi.cn/2508.html Spring Boot + Vue3 前后端分离 实战wiki知识库系统在当今的Web应用开发中,前后端分离已经成为了一种主流的开发模式。Spring...【详细内容】
2023-11-18  Search: Spring Boot  点击:(144)  评论:(0)  加入收藏
▌简易百科推荐
Qt与Flutter:在跨平台UI框架中哪个更受欢迎?
在跨平台UI框架领域,Qt和Flutter是两个备受瞩目的选择。它们各自具有独特的优势,也各自有着广泛的应用场景。本文将对Qt和Flutter进行详细的比较,以探讨在跨平台UI框架中哪个更...【详细内容】
2024-04-12  刘长伟    Tags:UI框架   点击:(1)  评论:(0)  加入收藏
Web Components实践:如何搭建一个框架无关的AI组件库
一、让人又爱又恨的Web ComponentsWeb Components是一种用于构建可重用的Web元素的技术。它允许开发者创建自定义的HTML元素,这些元素可以在不同的Web应用程序中重复使用,并且...【详细内容】
2024-04-03  京东云开发者    Tags:Web Components   点击:(8)  评论:(0)  加入收藏
Kubernetes 集群 CPU 使用率只有 13% :这下大家该知道如何省钱了
作者 | THE STACK译者 | 刘雅梦策划 | Tina根据 CAST AI 对 4000 个 Kubernetes 集群的分析,Kubernetes 集群通常只使用 13% 的 CPU 和平均 20% 的内存,这表明存在严重的过度...【详细内容】
2024-03-08  InfoQ    Tags:Kubernetes   点击:(19)  评论:(0)  加入收藏
Spring Security:保障应用安全的利器
SpringSecurity作为一个功能强大的安全框架,为Java应用程序提供了全面的安全保障,包括认证、授权、防护和集成等方面。本文将介绍SpringSecurity在这些方面的特性和优势,以及它...【详细内容】
2024-02-27  风舞凋零叶    Tags:Spring Security   点击:(55)  评论:(0)  加入收藏
五大跨平台桌面应用开发框架:Electron、Tauri、Flutter等
一、什么是跨平台桌面应用开发框架跨平台桌面应用开发框架是一种工具或框架,它允许开发者使用一种统一的代码库或语言来创建能够在多个操作系统上运行的桌面应用程序。传统上...【详细内容】
2024-02-26  贝格前端工场    Tags:框架   点击:(47)  评论:(0)  加入收藏
Spring Security权限控制框架使用指南
在常用的后台管理系统中,通常都会有访问权限控制的需求,用于限制不同人员对于接口的访问能力,如果用户不具备指定的权限,则不能访问某些接口。本文将用 waynboot-mall 项目举例...【详细内容】
2024-02-19  程序员wayn  微信公众号  Tags:Spring   点击:(39)  评论:(0)  加入收藏
开发者的Kubernetes懒人指南
你可以将本文作为开发者快速了解 Kubernetes 的指南。从基础知识到更高级的主题,如 Helm Chart,以及所有这些如何影响你作为开发者。译自Kubernetes for Lazy Developers。作...【详细内容】
2024-02-01  云云众生s  微信公众号  Tags:Kubernetes   点击:(51)  评论:(0)  加入收藏
链世界:一种简单而有效的人类行为Agent模型强化学习框架
强化学习是一种机器学习的方法,它通过让智能体(Agent)与环境交互,从而学习如何选择最优的行动来最大化累积的奖励。强化学习在许多领域都有广泛的应用,例如游戏、机器人、自动驾...【详细内容】
2024-01-30  大噬元兽  微信公众号  Tags:框架   点击:(68)  评论:(0)  加入收藏
Spring实现Kafka重试Topic,真的太香了
概述Kafka的强大功能之一是每个分区都有一个Consumer的偏移值。该偏移值是消费者将读取的下一条消息的值。可以自动或手动增加该值。如果我们由于错误而无法处理消息并想重...【详细内容】
2024-01-26  HELLO程序员  微信公众号  Tags:Spring   点击:(88)  评论:(0)  加入收藏
SpringBoot如何实现缓存预热?
缓存预热是指在 Spring Boot 项目启动时,预先将数据加载到缓存系统(如 Redis)中的一种机制。那么问题来了,在 Spring Boot 项目启动之后,在什么时候?在哪里可以将数据加载到缓存系...【详细内容】
2024-01-19   Java中文社群  微信公众号  Tags:SpringBoot   点击:(86)  评论:(0)  加入收藏
站内最新
站内热门
站内头条