在这个简短的教程中,我们将展示一些在 Java 中转义 JSON 字符串的方法。
我们将快速浏览最流行的 JSON 处理库以及它们如何使转义成为一项简单的任务。
让我们考虑一个简单但常见的用例,将用户指定的消息发送到 Web 服务。天真地,我们可以尝试:
String payload = "{"message":"" + message + ""}";
sendMessage(payload);
但是,实际上,这会带来很多问题。
最简单的是如果消息包含引号:
{ "message" : "My "message" breaks json" }
更糟糕的是用户可以故意破坏请求的语义。如果他发送:
Hello", "role" : "admin
然后消息变为:
{ "message" : "Hello", "role" : "admin" }
最简单的方法是用适当的转义序列替换引号:
String payload = "{"message":"" + message.replace(""", "\"") + ""}";
但是,这种方法非常脆弱:
需要对每个连接的值执行此操作,并且我们需要始终牢记我们已经转义了哪些字符串
此外,随着消息结构随时间变化,这可能会成为维护难题
而且很难阅读,更容易出错
简而言之,我们需要采用更通用的方法。不幸的是,原生 JSON 处理功能仍处于JEP 阶段,因此我们不得不将目光转向各种开源 JSON 库。
我们评论中最简单和最小的库是JSON-java,也称为org.json。
要构造一个 JSON 对象,我们只需创建一个JSONObject 的实例,并且基本上将它视为一个Map:
JSONObject jsonObject = new JSONObject();
jsonObject.put("message", "Hello "World"");
String payload = jsonObject.toString();
这将采用“世界”周围的引号并转义它们:
{
"message" : "Hello "World""
}
用于 JSON 处理的最流行和通用的 Java 库之一是Jackson。
乍一看,Jackson 的行为与 org.json类似:
Map<String, Object> params = new HashMap<>();
params.put("message", "Hello "World"");
String payload = new ObjectMapper().writeValueAsString(params);
但是,Jackson 也可以支持序列化 Java 对象。
因此,让我们通过将消息包装在自定义类中来稍微增强我们的示例:
class Payload {
Payload(String message) {
this.message = message;
}
String message;
// getters and setters
}
然后,我们需要一个 ObjectMapper的实例,我们可以将对象的实例传递给它:
String payload = new ObjectMapper().writeValueAsString(new Payload("Hello "World""));
在这两种情况下,我们都会得到与之前相同的结果:
{
"message" : "Hello "World""
}
如果我们有一个已经转义的属性并且需要在不进一步转义的情况下对其进行序列化,我们可能希望在该字段上使用 Jackson 的@JsonRawValue注释。
Gson 是 Google 的一个库,经常与 Jackson 正面交锋。
当然,我们可以再次像使用org.json 那样做:
JsonObject json = new JsonObject();
json.addProperty("message", "Hello "World"");
String payload = new Gson().toJson(gsonObject);
或者我们可以使用自定义对象,例如 Jackson:
String payload = new Gson().toJson(new Payload("Hello "World""));
我们将再次得到相同的结果。
你适合学Java吗?4大专业测评方法
代码逻辑 吸收能力 技术学习能力 综合素质
先测评确定适合在学习