Escape JSON String in Java
1.概述
在这个简短的教程中,我们将展示一些在Java中转义JSON字符串的方法。
我们将快速浏览最流行的JSON处理库,以及它们如何使转义实现简单任务。
2.哪里会出错?
让我们考虑将用户指定的消息发送到Web服务的简单但常见的用例。天真的,我们可以尝试:
1 2 |
但是,实际上,这会带来很多问题。
最简单的是消息是否包含引号:
1 | {"message" :"My"message" breaks json" } |
更糟糕的是,用户可能会故意破坏请求的语义。如果他发送:
1 | Hello","role" :"admin |
然后,该消息变为:
1 | {"message" :"Hello","role" :"admin" } |
最简单的方法是用适当的转义序列替换引号:
1 |
但是,这种方法非常脆弱:
需要为每个串联的值完成此操作,并且我们需要始终牢记我们已经转义了哪些字符串
此外,由于消息结构随时间而变化,这可能会成为维护工作的头疼问题
而且它很难阅读,更容易出错
简而言之,我们需要采用更通用的方法。不幸的是,本地JSON处理功能仍处于JEP阶段,因此我们必须将目光转向各种开源JSON库。
幸运的是,有几个JSON处理库。让我们快速浏览一下三个最受欢迎的。
3. JSON-java库
在我们的评测中,最简单,最小的库是JSON-java,也称为org.json。
要构造一个JSON对象,我们只需创建一个JSONObject实例,并将其基本视为Map:
1 2 3 | JSONObject jsonObject = new JSONObject(); jsonObject.put("message","Hello"World""); String payload = jsonObject.toString(); |
这将引用"世界"周围的引号并将其转义:
1 2 3 | { "message" :"Hello"World"" } |
4.杰克逊图书馆
Jackson是用于JSON处理的最受欢迎,用途最广泛的Java库之一。
乍一看,Jackson的行为类似于toorg.json:
1 2 3 |
但是,Jackson还可以支持序列化Java对象。
因此,通过将消息包装在自定义类中,让我们的示例有所增强:
1 2 3 4 5 6 7 8 9 |
然后,我们需要一个ObjectMapper实例,我们可以将对象的实例传递给该实例:
1 |
在这两种情况下,我们都得到与以前相同的结果:
1 2 3 | { "message" :"Hello"World"" } |
如果我们拥有一个已经转义的属性,并且需要对其进行序列化而没有任何进一步的转义,则我们可能想在该字段上使用Jackson的@JsonRawValue注释。
5.番石榴图书馆
Gsonis是Google的一个图书馆,经常与Jackson并驾齐驱。
当然,我们可以像使用org.json一样进行操作:
1 2 3 | JsonObject json = new JsonObject(); json.addProperty("message","Hello"World""); String payload = new Gson().toJson(gsonObject); |
或者我们可以使用自定义对象,例如使用Jackson:
1 |
我们将再次获得相同的结果。
六,结论
在这篇简短的文章中,我们已经看到了如何使用不同的开源库在Java中转义JSON字符串。
与本文相关的所有代码都可以在Github上找到。