介紹
最近涉及 Nginx 輸出的埋點(diǎn)日志,實(shí)時(shí)接入 Kafka,我需要實(shí)時(shí)解析 Kafka 中埋點(diǎn)日志,但是在解析過(guò)程中,出現(xiàn) \x22 這樣的字符,使我不能將字符串解析成 JSON 對(duì)象,本著解決問(wèn)題的想法進(jìn)行了研究,本文作為個(gè)人筆記,可供大家參考。
問(wèn)題說(shuō)明
- 問(wèn)題字符串樣例
{\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ì)字符串本身的問(wèn)題,進(jìn)行解決。
解決方案
- 將 \x22 替換成 " 或者 '
jsonData.replaceAll("\\x22", "\"")
- 使用提三方 jar 如 commons-lang3
\x 用于在 python 和其他語(yǔ)言中轉(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"""))