Java中反序列化含未转义引号的异常JSON数据处理方案
非法JSON双引号转义修复方案(Java实现)
问题本质
这类问题属于典型的非标准JSON解析问题:上游生成JSON时未正确转义字符串值内部的双引号,导致常规JSON库(Jackson/Gson/Fastjson等)无法区分「JSON语法结构的边界双引号」和「字符串内容里的普通双引号」,直接抛出解析异常。
给出的异常片段核心问题就是值内部的引号未做转义:
// 原异常JSON片段 "text":"[options="header", cols=".^6,^.^4, ^4,^.^4,^.^3"] ", "entity":"some text "some text" "
实现思路
不要尝试写正则直接匹配「需要转义的内部引号」,反向处理的思路稳定性更高,误判率极低:
- 先识别所有作为JSON语法边界的双引号,将这些引号替换为一个业务文本中绝对不会出现的特殊占位符
- 此时剩余的所有双引号全都是字符串值内部未转义的普通引号,统一替换为转义格式
\" - 把之前替换的特殊占位符还原为正常双引号,即可得到符合标准规范的合法JSON
- 后续直接用常规JSON库反序列化即可
边界引号识别规则
只有以下位置的双引号属于语法边界引号,其余全是需要转义的内部引号:
- 键名的前后引号:前面紧邻
{/,(允许中间存在空白字符),后面紧邻:(允许中间存在空白字符) - 字符串值的前后引号:前面紧邻
:(允许中间存在空白字符),后面紧邻,/}/](允许中间存在空白字符)
Java代码实现
import com.fasterxml.jackson.databind.ObjectMapper; import java.util.regex.Pattern; public class JsonFixUtil { // 选择业务文本中绝对不会出现的字符串作为占位符 private static final String QUOTE_PLACEHOLDER = "__STRUCT_QUOTE_FLAG_20240628__"; private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); /** * 修复因字符串内部未转义双引号导致的非法JSON * @param brokenJson 异常JSON字符串 * @return 修复后的标准JSON字符串 */ public static String fixUnescapedQuotes(String brokenJson) { String processed = brokenJson; // 匹配所有结构边界的双引号,替换为占位符,自动跳过引号和语法符号间的空白字符 Pattern structQuotePattern = Pattern.compile("(?<=([{,:\\[\\]]|^)\\s*)\"|\"(?=\\s*([},:\\]\\]]|$))"); processed = structQuotePattern.matcher(processed).replaceAll(QUOTE_PLACEHOLDER); // 剩余所有双引号都是内部未转义引号,统一加转义符 processed = processed.replace("\"", "\\\""); // 还原边界引号 processed = processed.replace(QUOTE_PLACEHOLDER, "\""); return processed; } // 测试用例 public static void main(String[] args) throws Exception { String brokenJson = """ { "text":"[options="header", cols=".^6,^.^4, ^4,^.^4,^.^3"] ", "entity":"some text "some text" " } """; String fixedJson = fixUnescapedQuotes(brokenJson); System.out.println("修复后JSON:" + fixedJson); // 直接用Jackson反序列化无异常 Object result = OBJECT_MAPPER.readValue(fixedJson, Object.class); System.out.println("反序列化结果:" + result); } }
注意事项
- 如果原始JSON除了未转义引号之外,还存在缺逗号、缺括号、键名未加引号这类结构错误,需要先修复结构问题再使用上述方法处理
- 占位符可以根据自身业务场景调整,只要保证不会和正常文本内容冲突即可
- 修复完成后建议加一层JSON校验逻辑,如果修复后依然解析失败,可以打日志留档排查边缘case
内容的提问来源于stack exchange,提问作者ChillBoy
相关产品推荐
相关产品推荐

