介绍
最近涉及 Nginx 输出的埋点日志,实时接入 Kafka,我需要实时解析 Kafka 中埋点日志,但是在解析过程中,出现 \x22
这样的字符,使我不能将字符串解析成 JSON 对象,本着解决问题的想法进行了研究,本文作为个人笔记,可供大家参考。
问题说明
- 问题字符串样例
{\x22documentReferer\x22:\x22http:\x5C/\x5C/pikabu.ru\x5C/freshitems.php\x22}
上述字符串是不能直接解析成 json 字符串的,错误如下:
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 是怎么产生的
\x22 实际上是 Nginx 产生的,它的真实值可以是 " 或者 ',如下:
{"documentReferer":"http:\x5C/\x5C/pikabu.ru\x5C/freshitems.php"}
由于本着麻烦别人,不如麻烦自己的原则,忽略产生的原因,针对字符串本身的问题,进行解决。
解决方案
- 将 \x22 替换成 " 或者 '
jsonData.replaceAll("\\x22", "\"")
- 使用提三方 jar 如 commons-lang3
\x 用于在 python 和其他语言中转义 ASCII 字符,在 Scala 和 Java 中,可以使用\u`` 转义 Unicode 字符。由于 ASCII 是 Unicode 的一个子集,可以使用
unescapeJava方法 (在 StringEscapeUtils 中 ),还有一些简单的更换以及添加
\u``` 2个前导零一起转义字符。
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"""))
网友评论