JEP 540:Java 原生 JSON API 来了
JEP 540: Simple JSON API (Now in Incubator)
Java 平台终于迎来了原生 JSON 支持。JEP 540 提出了一套简单标准的 API,让开发者无需依赖 Jackson 或 Gson 等外部库,就能轻松解析和生成 JSON 文档。该 API 严格遵循 RFC 8259 标准,专注于低代码量的核心任务,旨在让 Java 处理 JSON 像 Python 或 Go 一样简洁。从配置文件的优化到快速探索数据结构,这一孵化期特性将显著提升开发效率,让 JDK 自身也能原生处理 JSON,彻底告别繁琐的依赖管理。
我们处理简单任务时,Java 代码应该和 Python 或 Go 代码一样简单。
HN 评论区
82- dfabulich
该 API 的一个既定目标是实现“低仪式感”(low ceremony);但这看起来仪式感太重了。
IO.println(JsonObject.of(Map.of("providers",
JsonArray.of(List.of(JsonString.of("SUN"),
JsonString.of("SunRsaSign"),
JsonString.of("SunEC"))))));
肯定有更好的办法!
按理说,应该有一种方式能直接创建包含原生 Java String、Boolean、Double 和 Integer 的 JsonArray,而不需要客户端显式地将每个值转换为 JsonValue。而且,为什么我被迫要把一个原生 List 转换成 JsonArray,仅仅是为了把它作为 JsonObject 的值?
为什么我不能这样写?
JsonObject.of(Map.of("providers", List.of("SUN", "SunRsaSign", "SunEC")));
- whaley
与此同时,Jackson 已经稳健运行了近 20 年 https://github.com/FasterXML/jackson。
Jackson 我最喜欢的功能之一,就是在 jackson.databind 中能够通过丰富且流式的 API(JsonNode)随意遍历文档,这个 JEP 至少在概念上通过 JsonValue 抽象借鉴了这一点。这两者都比其他一些实现要好,在其他实现中,你实际上是在操作一个美其名曰的 Map<String,Object>。
- whartung
嗯,这将会很有趣。
我手头已经有一个这样的东西了(我相信我不是唯一一个)。它大概有 500 行代码。
我发现我并不太喜欢这种 JAX-B 风格的 Java 对象 JSON 序列化。我不想贬低它们,它们确实有用,也非常流行,我只是不喜欢跟它们较劲。手动编写 JSON 编组代码对我来说并不算艰难(尤其是有了我的工具层之后)。(另外,从哲学上讲,我尽可能避免代码中出现“魔法”。)
当然,我仍然需要一个解析器,我使用的是 GSON 的解析器,这意味着我仍然不得不引入整个 Bean 级别的序列化基础设施。我只是不用它而已。虽然我之前也写过 JSON 解析器,但我觉得引入现成的比自己去维护更好。所以从这个意义上说,这是个喜忧参半的局面。
不过,我确实挺喜欢用它。
这将成为 JDK 一项值得拥有的能力。理想情况下,它能取代我的那个。
- nikeee
我不喜欢这样:
String body = ... REST 响应体,这是一个 JSON 文档 ... ;
JsonValue json = Json.parse(body);
json.get("properties").get("periods").asList().stream()
.mapToInt(j -> j.get("temperature").asInt())
.average()
.ifPresent(IO::println);
为什么我能在 JsonValue 上调用 `.get(string)` 或 `.get(int)`?这些方法不应该在 JsonObject 和 JsonArray 上吗?
> 如果 JsonValue 实例类型错误,或者请求的成员或元素不存在,访问方法将抛出 JsonValueException。
所以如果我捕获到异常,我无法判断是因为值类型错误,还是因为对象根本没有请求的键?这在我看来是个典型的陷阱(footgun)。
他们刚把模式匹配(pattern matching)引入 Java。为什么不让那些 .get 方法移到 JsonArray 和 JsonObject 上?那样就能解决这种混淆。这样我们就能直接使用类似 `if (json instanceof JsonObject o) o.get("properties")` 的写法了。
- gavinray
过去,如果你想在 JVM 上构建 Web 服务,你需要两样东西:
1. 一个 HTTP 服务器库/框架
2. 一个 JSON 库
JDK 18 通过 "HttpHandlers"、"SimpleFileServer" 以及 "jwebserver" CLI 提供了一个性能不错且无偏见(unopinionated)的 HTTP 服务器。
后来它又获得了虚拟线程(Virtual Thread)支持,这让其性能和可扩展性极具竞争力。
有了 JSON 模块,你终于不再需要依赖外部库就能无痛地构建基本的 JVM Web 服务了。
现在,我们只需要一个像 picocli 那样得体的 CLI 框架,或者至少是 Python 标准库里的 "argparse"……