优雅!Spring Boot 3.3 搭配 JSON Schema 实现灵活的 JSON 数据定义与验证
在现代互联网应用中,数据验证在提高数据质量和保证系统稳定性方面扮演着至关重要的角色。随着微服务架构的广泛应用,各个服务之间的通信和交互往往依赖 JSON 格式的数据。在这种场景下,确保接收到的 JSON 数据满足某些特定的格式和规则显得尤为重要。JSON Schema 是一种定义 JSON 数据结构的标准,能够有效帮助开发者验证传输数据的正确性。
运行效果:
若想获取项目完整代码以及其他文章的项目源码,且在代码编写时遇到问题需要咨询交流,欢迎加入下方的知识星球。
本篇文章将结合 Spring Boot 3.3 框架,介绍如何使用 JSON Schema Validator 进行灵活且强大的 JSON 数据定义与验证。我们将通过创建一个完整的前后端示例,展示如何优雅地管理和验证 JSON 数据。
项目结构
我们将创建一个简单的用户验证示例,包括后端的 JSON Schema 验证和前端的用户输入数据校验。项目结构如下:
json-schema-validator
├── pom.xml
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── icoderoad
│ │ │ └── jsonvalidator
│ │ │ ├── controller
│ │ │ │ └── JsonValidatorController.java
│ │ │ ├── service
│ │ │ │ └── JsonSchemaValidatorService.java
│ │ │ └── entity
│ │ │ └── User.java
│ │ ├── resources
│ │ │ ├── application.yml
│ │ │ ├── templates
│ │ │ │ └── index.html
│ │ │ └── schemas
│ │ │ └── user-schema.json
pom.xml 配置
首先在 pom.xml
中引入所需依赖,包括 Spring Boot Web、Lombok 和 JSON Schema Validator。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.icoderoad</groupId>
<artifactId>json-schema-validator</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>json-schema-validator</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!-- JSON Schema Validator -->
<dependency>
<groupId>com.github.java-json-tools</groupId>
<artifactId>json-schema-validator</artifactId>
<version>2.2.14</version>
</dependency>
<!-- Thymeleaf 模板引擎 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.yml 配置
在 application.yml
文件中定义 JSON Schema 文件的路径,这里将其保存在 schemas/
目录下。
server:
port: 8080
json:
schema-path: /schemas/user-schema.json
JSON Schema 文件
在 resources/schemas/
目录下创建 user-schema.json
文件,定义用户 JSON 数据的规则:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "User",
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 2,
"maxLength": 100
},
"age": {
"type": "integer",
"minimum": 0
},
"email": {
"type": "string",
"format": "email"
}
},
"required": ["name", "age", "email"]
}
该 schema 定义了 name
(字符串类型,长度为 2-100 个字符)、age
(整数类型,最小值为 0)、email
(必须是有效的邮箱格式),并要求所有字段为必填。
配置类
通过 @ConfigurationProperties
读取 application.yml
中的 json.schema-path
配置。
package com.icoderoad.jsonvalidator.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Data
@Configuration
@ConfigurationProperties(prefix = "json")
public class JsonSchemaProperties {
private String schemaPath;
}
实体类
创建用户实体类 User
,使用 Lombok 简化代码:
package com.icoderoad.jsonvalidator.entity;
import lombok.Data;
@Data
public class User {
private String name;
private Integer age;
private String email;
}
服务类
实现 JSON Schema 验证逻辑,使用 json-schema-validator
库来解析和验证 JSON 数据。
package com.icoderoad.jsonvalidator.service;
import java.io.IOException;
import java.io.InputStream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.fge.jsonschema.core.exceptions.ProcessingException;
import com.github.fge.jsonschema.core.report.ProcessingReport;
import com.github.fge.jsonschema.main.JsonSchema;
import com.github.fge.jsonschema.main.JsonSchemaFactory;
import com.icoderoad.jsonvalidator.config.JsonSchemaProperties;
@Service
public class JsonSchemaValidatorService {
@Autowired
private JsonSchemaProperties jsonSchemaProperties;
private final ObjectMapper objectMapper = new ObjectMapper();
public ProcessingReport validateUserSchema(String jsonData) throws IOException {
// 读取 JSON Schema 文件
InputStream schemaStream = getClass().getResourceAsStream(jsonSchemaProperties.getSchemaPath());
JsonNode schemaNode = objectMapper.readTree(schemaStream);
// 创建 JSON Schema 对象
JsonSchemaFactory schemaFactory = JsonSchemaFactory.byDefault();
JsonSchema jsonSchema;
try {
jsonSchema = schemaFactory.getJsonSchema(schemaNode);
// 解析要验证的 JSON 数据
JsonNode jsonNode = objectMapper.readTree(jsonData);
// 执行验证
return jsonSchema.validate(jsonNode);
} catch (ProcessingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
控制器类
优化后的控制器提供一个 POST
接口供前端验证 JSON 数据,并在返回结果时结合 Bootstrap
风格进行提示展示。
package com.icoderoad.jsonvalidator.controller;
import com.github.fge.jsonschema.core.report.ProcessingReport;
import com.icoderoad.jsonvalidator.service.JsonSchemaValidatorService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class JsonValidatorController {
@Autowired
private JsonSchemaValidatorService validatorService;
@GetMapping("/")
public String home() {
return "index";
}
@PostMapping("/validate")
@ResponseBody
public String validateJson(@RequestBody String userData, Model model) {
try {
ProcessingReport report = validatorService.validateUserSchema(userData);
if (report.isSuccess()) {
return "<div class='alert alert-success'>验证成功!</div>";
} else {
return "<div class='alert alert-danger'>验证失败:" + report.toString() + "</div>";
}
} catch (Exception e) {
return "<div class='alert alert-danger'>验证过程中出现错误:" + e.getMessage() + "</div>";
}
}
}
前端代码
前端使用 Thymeleaf 模板引擎,结合 jQuery 和 Bootstrap 创建表单,并调用后端接口来进行 JSON 验证。
在 src/main/resources/templates/
目录下创建 index.html
文件。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>JSON Schema 验证</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<div class="container">
<h1>用户数据验证</h1>
<form id="userForm">
<div class="mb-3">
<label for="name" class="form-label">姓名</label>
<input type="text" class="form-control" id="name" name="name" required>
</div>
<div class="mb-3">
<label for="age" class="form-label">年龄</label>
<input type="number" class="form-control" id="age" name="age" required>
</div>
<div class="mb-3">
<label for="email" class="form-label">邮箱</label>
<input type="email" class="form-control" id="email" name="email" required>
</div>
<button type="submit" class="btn btn-primary">提交</button>
</form>
<div id="result"></div>
</div>
<script>
$('#userForm').submit(function (e) {
e.preventDefault();
var userData = {
name: $('#name').val(),
age: parseInt($('#age').val()),
email: $('#email').val()
};
$.ajax({
url: '/validate',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(userData),
success: function (response) {
$('#result').html(response);
},
error: function () {
$('#result').html("<div class='alert alert-danger'>请求失败!</div>");
}
});
});
</script>
</body>
</html>
结语
通过本文的示例,我们可以看到如何利用 Spring Boot 3.3 和 JSON Schema 有效地实现 JSON 数据的定义与验证。这种方法灵活、易于扩展,特别适合于需要动态处理和验证 JSON 数据的场景。JSON Schema 的使用不仅能确保数据的结构和完整性,还能帮助开发者在处理外部数据时提高安全性和可靠性。在未来的开发中,JSON Schema 还能与 API 文档、自动生成工具结合使用,进一步提升开发效率。