介紹
最近涉及 Nginx 輸出的埋點(diǎn)日志,實(shí)時(shí)接入 Kafka仗岸,我需要實(shí)時(shí)解析 Kafka 中埋點(diǎn)日志允耿,但是在解析過程中,出現(xiàn) \x22
這樣的字符扒怖,使我不能將字符串解析成 JSON 對(duì)象较锡,本著解決問題的想法進(jìn)行了研究,本文作為個(gè)人筆記,可供大家參考盗痒。
問題說明
- 問題字符串樣例
{\x22documentReferer\x22:\x22http:\x5C/\x5C/pikabu.ru\x5C/freshitems.php\x22}
上述字符串是不能直接解析成 json 字符串的蚂蕴,錯(cuò)誤如下:
Exception in thread "main" com.alibaba.fastjson.JSONException: illegal identifier : \pos 1, json : {\x22documentReferer\x22:\x22http:\x5C/\x5C/pikabu.ru\x5C/freshitems.php\x22}
at com.alibaba.fastjson.parser.JSONLexerBase.scanSymbolUnQuoted(JSONLexerBase.java:829)
at com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONParser.java:286)
at com.alibaba.fastjson.parser.DefaultJSONParser.parse(DefaultJSONParser.java:1356)
at com.alibaba.fastjson.parser.DefaultJSONParser.parse(DefaultJSONParser.java:1322)
at com.alibaba.fastjson.JSON.parse(JSON.java:152)
at com.alibaba.fastjson.JSON.parse(JSON.java:162)
at com.alibaba.fastjson.JSON.parse(JSON.java:131)
at com.alibaba.fastjson.JSON.parseObject(JSON.java:223)
at com.test.JsonDataParseTest$.main(JsonDataParseTest.scala:19)
at com.test.JsonDataParseTest.main(JsonDataParseTest.scala)
- \x22 是怎么產(chǎn)生的
\x22 實(shí)際上是 Nginx 產(chǎn)生的,它的真實(shí)值可以是 " 或者 '俯邓,如下:
{"documentReferer":"http:\x5C/\x5C/pikabu.ru\x5C/freshitems.php"}
由于本著麻煩別人骡楼,不如麻煩自己的原則,忽略產(chǎn)生的原因稽鞭,針對(duì)字符串本身的問題鸟整,進(jìn)行解決。
解決方案
- 將 \x22 替換成 " 或者 '
jsonData.replaceAll("\\x22", "\"")
- 使用提三方 jar 如 commons-lang3
\x 用于在 python 和其他語言中轉(zhuǎn)義 ASCII 字符朦蕴,在 Scala 和 Java 中篮条,可以使用\u`` 轉(zhuǎn)義 Unicode 字符。由于 ASCII 是 Unicode 的一個(gè)子集吩抓,可以使用
unescapeJava方法 (在 StringEscapeUtils 中 )涉茧,還有一些簡(jiǎn)單的更換以及添加
\u``` 2個(gè)前導(dǎo)零一起轉(zhuǎn)義字符。
maven pom.xml 引用:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
<!--<scope>provided</scope>-->
</dependency>
示例代碼:
import org.apache.commons.lang3.StringEscapeUtils
StringEscapeUtils.unescapeJava(x.replaceAll("""\\x""", """\\u00"""))