1. 概述
在本簡短教程中,我們將演示一些在 Java 中轉義 JSON 字符串的方法。
我們將快速瀏覽一些最流行的 JSON 處理庫以及它們如何使轉義變得簡單。
2. 可能會出錯的情況?
讓我們考慮一個簡單的但常見的用例:將用户指定的消息發送到 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 階段http://openjdk.java.net/jeps/198,因此我們必須將目光投向各種開源 JSON 庫。
幸運的是,有若干 JSON 處理庫。讓我們快速瞭解一下最流行的三個。
3. JSON-java 庫
JSON-java,也稱為 org.json,是我們所評測中最簡單、最小的庫。
要構造一個 JSON 對象,我們只需創建 JSONObject 的實例,並將其視為一個 Map:
JSONObject jsonObject = new JSONObject();
jsonObject.put("message", "Hello \"World\"");
String payload = jsonObject.toString();這將會處理“World”中的引號並進行轉義:
{
"message" : "Hello \"World\""
}4. Jackson 庫
Jackson 是用於 JSON 處理最受歡迎且用途最廣泛的 Java 庫之一。
初次查看時,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 註解來標記該字段。
5. Gson 庫
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\""));我們再次會得到相同的結果。
6. 結論
在本文中,我們瞭解到如何使用不同的開源庫在 Java 中轉義 JSON 字符串。