JSON:在JSON字符串中转义双引号

时间:2018-06-11 10:15:38

标签: java json regex

我有一个像这样的JSON字符串:

 {
       "serviceName":"Data file "%s" was deleted successfully.",
       "serviceInstance":"esm-session-service"
     }

我正在尝试使用ObjectMapper将JSON上面映射到对象,如下所示:

Message messageObject = objectMapper.readValue(messageJson, Message.class);

下面是堆栈跟踪输出:

com.fasterxml.jackson.core.JsonParseException: Unexpected character ('%' (code 37)): was expecting comma to separate Object entries
 at [Source: (String)"{"serviceName":"\"Data file \""%s"serviceInstance":"esm-session-service"}r""; line: 1, column: 33]
    at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1804)
    at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:663)
    at com.fasterxml.jackson.core.base.ParserMinimalBase._reportUnexpectedChar(ParserMinimalBase.java:561)
    at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._skipComma(ReaderBasedJsonParser.java:2271)
    at com.fasterxml.jackson.core.json.ReaderBasedJsonParser.nextFieldName(ReaderBasedJsonParser.java:892)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:295)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4001)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2992)
    at com.test.json.TestJsonObjectConversion.main(TestJsonObjectConversion.java:77)

我知道问题在于JSON中的“%s”,我无法找到任何方法只能在“%s”中转义引号。

我期待低于JSON:

{
  "serviceName":"Data file \"%s\" was deleted successfully.",
  "serviceInstance":"esm-session-service"
}

提前致谢。

1 个答案:

答案 0 :(得分:0)

问题是从Elastic Search接收无效的JSON字符串,其中双引号未被转义。

如果您无法通过Elastic Search(寻找最新版本)找到更正,则修补程序会按顺序排列:

假设键值对占用一行:

从java 9开始:

String json = ...;
json = json.replaceAll(":\\s*\"(.*)\"",
        (m) -> {
            String value = m.group(1);
            value = value.replaceAll("(?!\\)\"", "\\\\\");
            return ":\"" + value + "\"";
        });

这将使value填充双引号之间的最长序列。 负前瞻(?!\\)检查没有反斜杠已经在内部双引号之前。

也许更好的方法是通过Apache Common Text StringEscapeUtils整体转义字符串值:

json = json.replaceAll(":\\s*\"(.*)\"",
        (m) -> ":\"" + StringEscapeUtils.escapeJson(m.group(1)) + "\"");

在java 9之前,需要一个用于正则表达式替换的循环。 如果键值对不在一行(如包含换行符的值),则正则表达式需要执行多行,DOT_ALL。

可以通过StringReader传递生成的JSON字符串。