更新時(shí)間:2022-10-18 10:58:35 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽4597次
在這個(gè)簡(jiǎn)短的教程中,我們將展示一些在 Java 中轉(zhuǎn)義 JSON 字符串的方法。
我們將快速瀏覽最流行的 JSON 處理庫(kù)以及它們?nèi)绾问罐D(zhuǎn)義成為一項(xiàng)簡(jiǎn)單的任務(wù)。
讓我們考慮一個(gè)簡(jiǎn)單但常見(jiàn)的用例,將用戶指定的消息發(fā)送到 Web 服務(wù)。天真地,我們可以嘗試:
String payload = "{\"message\":\"" + message + "\"}";
sendMessage(payload);
但是,實(shí)際上,這會(huì)帶來(lái)很多問(wèn)題。
最簡(jiǎn)單的是如果消息包含引號(hào):
{ "message" : "My "message" breaks json" }
更糟糕的是用戶可以故意破壞請(qǐng)求的語(yǔ)義。如果他發(fā)送:
Hello", "role" : "admin
然后消息變?yōu)椋?/p>
{ "message" : "Hello", "role" : "admin" }
最簡(jiǎn)單的方法是用適當(dāng)?shù)霓D(zhuǎn)義序列替換引號(hào):
String payload = "{\"message\":\"" + message.replace("\"", "\\\"") + "\"}";
但是,這種方法非常脆弱:
需要對(duì)每個(gè)連接的值執(zhí)行此操作,并且我們需要始終牢記我們已經(jīng)轉(zhuǎn)義了哪些字符串
此外,隨著消息結(jié)構(gòu)隨時(shí)間變化,這可能會(huì)成為維護(hù)難題
而且很難閱讀,更容易出錯(cuò)
簡(jiǎn)而言之,我們需要采用更通用的方法。不幸的是,原生 JSON 處理功能仍處于JEP 階段,因此我們不得不將目光轉(zhuǎn)向各種開(kāi)源 JSON 庫(kù)。
我們?cè)u(píng)論中最簡(jiǎn)單和最小的庫(kù)是JSON-java,也稱為org.json。
要構(gòu)造一個(gè) JSON 對(duì)象,我們只需創(chuàng)建一個(gè)JSONObject 的實(shí)例,并且基本上將它視為一個(gè)Map:
JSONObject jsonObject = new JSONObject();
jsonObject.put("message", "Hello \"World\"");
String payload = jsonObject.toString();
這將采用“世界”周圍的引號(hào)并轉(zhuǎn)義它們:
{
"message" : "Hello \"World\""
}
用于 JSON 處理的最流行和通用的 Java 庫(kù)之一是Jackson。
乍一看,Jackson 的行為與 org.json類似:
Map<String, Object> params = new HashMap<>();
params.put("message", "Hello \"World\"");
String payload = new ObjectMapper().writeValueAsString(params);
但是,Jackson 也可以支持序列化 Java 對(duì)象。
因此,讓我們通過(guò)將消息包裝在自定義類中來(lái)稍微增強(qiáng)我們的示例:
class Payload {
Payload(String message) {
this.message = message;
}
String message;
// getters and setters
}
然后,我們需要一個(gè) ObjectMapper的實(shí)例,我們可以將對(duì)象的實(shí)例傳遞給它:
String payload = new ObjectMapper().writeValueAsString(new Payload("Hello \"World\""));
在這兩種情況下,我們都會(huì)得到與之前相同的結(jié)果:
{
"message" : "Hello \"World\""
}
如果我們有一個(gè)已經(jīng)轉(zhuǎn)義的屬性并且需要在不進(jìn)一步轉(zhuǎn)義的情況下對(duì)其進(jìn)行序列化,我們可能希望在該字段上使用 Jackson 的@JsonRawValue注釋。
Gson 是 Google 的一個(gè)庫(kù),經(jīng)常與 Jackson 正面交鋒。
當(dāng)然,我們可以再次像使用org.json 那樣做:
JsonObject json = new JsonObject();
json.addProperty("message", "Hello \"World\"");
String payload = new Gson().toJson(gsonObject);
或者我們可以使用自定義對(duì)象,例如 Jackson:
String payload = new Gson().toJson(new Payload("Hello \"World\""));
我們將再次得到相同的結(jié)果。
相關(guān)閱讀
Java實(shí)驗(yàn)班
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
Java就業(yè)班
有基礎(chǔ) 直達(dá)就業(yè)
Java夜校直播班
業(yè)余時(shí)間 高薪轉(zhuǎn)行
Java在職加薪班
工作1~3年,加薪神器
Java架構(gòu)師班
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問(wèn)老師會(huì)電話與您溝通安排學(xué)習(xí)