Java 开发人员经常羡慕 JavaScript 解析 JSON 的简便性。尽管 Java 提供了更多的健壮性,但它往往涉及更多的工作和样板代码。多亏了 Manifold 项目,Java 现在有可能在解析和处理 JSON 文件方面超越 JavaScript。 Manifold 是一组革命性的 Java 语言扩展,它完全改变了我们处理 JSON(以及更多……)的方式。 https://www.youtube.com/watch?v=AoBnGZ7q6rk&embedable=true 歧管入门 本教程的代码可以在我的 上找到。 Manifold 相对年轻,但其功能已经非常强大。您可以在他们的网站和 Slack 频道上了解有关该项目的更多信息。 GitHub 页面 首先,您需要安装 Manifold 插件,该插件目前仅适用于 JetBrains IDE。该项目支持 Java 的 LTS 版本,包括最新的 JDK 19。 我们可以通过导航到市场并搜索 Manifold 从 IntelliJ/IDEAs 设置 UI 安装插件。该插件确保 IDE 不会与 Maven/Gradle 插件完成的工作发生冲突。 Manifold 由多个较小的项目组成,每个项目都提供自定义语言扩展。今天,我们将讨论一个这样的扩展,但还有更多内容需要探索。 设置 Maven 项目 为了演示 Manifold,我们将使用一个简单的 Maven 项目(它也适用于 Gradle)。我们首先需要从他们的网站粘贴当前的 Manifold 版本并添加必要的依赖项。 JSON 的主要依赖项是 依赖项。 manifold-json-rt 可以添加其他依赖项以支持 YAML、XML 和 CSV。我们需要将它添加到项目中的 文件中。 pom.xml 我知道具有讽刺意味的是,JSON 的样板文件减少始于 Maven 构建脚本中的大量配置。但这是配置,而不是“实际代码”;它主要是复制和粘贴。 请注意,如果您想减少此代码,Gradle 等效代码相比之下更简洁。 此行需要进入属性部分: <manifold.version>2023.1.5</manifold.version> 我们使用的依赖项是: <dependencies> <dependency> <groupId>systems.manifold</groupId> <artifactId>manifold-json-rt</artifactId> <version>${manifold.version}</version> </dependency> 编译插件是将 Manifold 编织到字节码中并使我们无缝衔接的样板。这是 pom 设置的最后一部分: <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <source>19</source> <target>19</target> <encoding>UTF-8</encoding> <compilerArgs> <!-- Configure manifold plugin--> <arg>-Xplugin:Manifold</arg> </compilerArgs> <!-- Add the processor path for the plugin --> <annotationProcessorPaths> <path> <groupId>systems.manifold</groupId> <artifactId>manifold-json</artifactId> <version>${manifold.version}</version> </path> </annotationProcessorPaths> </configuration> </plugin> </plugins> </build> 设置完成后,让我们深入研究代码。 使用 Manifold 解析 JSON 我们将示例 JSON 文件放在资源层次结构下的项目目录中。我把这个文件放在 下: src/main/resources/com/debugagent/json/Test.json { "firstName": "Shai", "surname": "Almog", "website": "https://debugagent.com/", "active": true, "details":[ {"key": "value"} ] } 在主类中,我们刷新 Maven 项目,您会注意到出现了一个新的 Test 类。这个类是Manifold根据JSON文件动态创建的。如果您更改 JSON 并刷新 Maven,一切都会无缝更新。 重要的是要了解 Manifold 不是代码生成器。它将我们刚刚写入的 JSON 编译成字节码。 Test 类带有几个内置功能,例如类型安全的构建器 API,它允许您使用构建器方法构建 JSON 对象。您还可以使用 和 方法生成嵌套对象并将 JSON 转换为字符串。 write() toJson() 这意味着我们现在可以写: Test test = Test.builder().withFirstName("Someone") .withSurname("Surname") .withActive(true) .withDetails(List.of( Test.details.detailsItem.builder(). withKey("Value 1").build() )) .build(); 这将打印出以下 JSON: { "firstName": "Someone", "surname": "Surname", "active": true, "details": [ { "key": "Value 1" } ] } 我们可以类似地使用如下代码读取 JSON 文件: Test readObject = Test.load().fromJson(""" { "firstName": "Someone", "surname": "Surname", "active": true, "details": [ { "key": "Value 1" } ] } """); 请注意使用 Java 15 语法编写长字符串。 方法返回一个对象,其中包含用于读取 JSON 的各种 API。在这种情况下,它是从一个 中读取的,但是有一些 API 可以从 URL、文件等中读取它。 TextBlock load() String Manifold 支持各种格式,包括 CSV、XML 和 YAML,允许您生成和解析这些格式中的任何一种,而无需编写任何样板代码或牺牲类型安全性。为了添加该支持,我们需要向 pom.xml 文件添加额外的依赖项: <dependency> <groupId>systems.manifold</groupId> <artifactId>manifold-csv-rt</artifactId> <version>${manifold.version}</version> </dependency> <dependency> <groupId>systems.manifold</groupId> <artifactId>manifold-xml-rt</artifactId> <version>${manifold.version}</version> </dependency> <dependency> <groupId>systems.manifold</groupId> <artifactId>manifold-yaml-rt</artifactId> <version>${manifold.version}</version> </dependency> </dependencies> 使用这些额外的依赖项,此代码将打印出与 JSON 文件相同的数据......使用 输出将是: test.write().toCsv() "firstName","surname","active","details" "Someone","Surname","true","[manifold.json.rt.api.DataBindings@71070b9c]" 请注意,逗号分隔值 (CSV) 输出不包含层次结构信息。这是 CSV 格式的限制,而不是 Manifold 的错误。 使用 时,输出很熟悉而且非常简洁: test.write().toXml() <root_object firstName="Someone" surname="Surname" active="true"> <details key="Value 1"/> </root_object> 使用 我们再次得到熟悉的打印输出: test.write().toYaml() firstName: Someone surname: Surname active: true details: - key: Value 1 使用 JSON 模式 Manifold 还可以与 JSON 模式无缝协作,允许您执行严格的规则和约束。这在处理日期和枚举时特别有用。 Manifold 无缝地创建/更新符合模式的字节码,使得处理复杂的 JSON 数据变得更加容易。 此架构是从 复制并粘贴的: Manifold GitHub 项目 { "$schema": "http://json-schema.org/draft-07/schema#", "$id": "http://example.com/schemas/User.json", "type": "object", "definitions": { "Gender": { "type": "string", "enum": ["male", "female"] } }, "properties": { "name": { "type": "string", "description": "User's full name.", "maxLength": 80 }, "email": { "description": "User's email.", "type": "string", "format": "email" }, "date_of_birth": { "type": "string", "description": "Date of uses birth in the one and only date standard: ISO 8601.", "format": "date" }, "gender": { "$ref" : "#/definitions/Gender" } }, "required": ["name", "email"] } 这是一个相对简单的架构,但我想在这里将您的注意力转移到几件事上。它根据需要定义名称和电子邮件。这就是为什么当我们尝试在 Manifold 中使用构建器创建 对象时, 方法需要两个参数: User build() User.builder("Name", "email@domain.com") 那只是开始……该架构包括一个日期。日期在 JSON 中是一个痛苦的前景,标准化很差并且充满了问题。该模式还包括一个实际上是枚举的性别字段。 使用 LocalDate 等常见的 Java 类,这一切都被转换为类型安全的语义: User u = User.builder("Name", "email@domain.com") .withDate_of_birth(LocalDate.of(1999, 10, 11)) .withGender(User.Gender.male) .build(); 这可以通过静态导入变得更短,但这个想法的要点很清楚。 JSON 在 Manifold 中是 Java 的有效原生。 冰山一角 Manifold 是一个强大而令人兴奋的项目。它彻底改变了 Java 中的 JSON 解析,但这只是它能做的一小部分! 在这篇文章中,我们只触及了其功能的表面。在下一篇文章中,我们将更深入地研究 Manifold 并探索一些额外的意想不到的功能。 请在评论部分分享您对 Manifold 的体验和想法。如果您有任何问题,请随时提出。