Gson解析无引号非标准JSON时如何让regexValue被识别为字符串
核心问题原因
你从消息队列拿到的不是标准JSON格式:所有属性名、字符串值都没有双引号包裹,Gson默认的词法分析阶段会先扫描token,碰到regexValue:后的[会直接判定为数组的开始标记,但是后续内容不符合数组语法,所以在调用你的自定义反序列化器之前就会抛出MalformedJsonException异常。
解决方案
方案1:上游输出标准化(优先选择)
如果可以调整消息队列上游的生成逻辑,直接让上游输出标准JSON,所有字符串类型的键和值都用双引号包裹,从根源解决问题,无需额外适配。方案2:原始JSON预处理
如果无法调整上游逻辑,可以先对原始JSON字符串做正则替换,补全所需的双引号后再交给Gson解析,示例代码如下:
// 第一步:给所有属性名补双引号 String processedJson = rawJson.replaceAll("(\\w+):", "\"$1\":"); // 第二步:给regexValue的正则值补双引号,处理转义 processedJson = processedJson.replaceAll("\"regexValue\":([^,}]+)", "\"regexValue\":\"$1\""); // 处理完成后正常解析 Gson gson = new Gson(); TableDefinition tableDefinition = gson.fromJson(processedJson, TableDefinition.class);
注意:如果你的正则表达式中包含
,或}字符,需要调整正则匹配规则适配场景。
- 方案3:开启Gson宽松模式+自定义TypeAdapter
如果不想做字符串预处理,可以开启Gson的宽松解析模式,同时为包含regexValue的Regex类自定义TypeAdapter,手动控制字段解析逻辑,示例代码如下:
首先实现Regex类的自定义解析适配器:
public class RegexAdapter extends TypeAdapter<Regex> { @Override public Regex read(JsonReader in) throws IOException { Regex regex = new Regex(); in.beginObject(); while (in.hasNext()) { String fieldName = in.nextName(); if ("regexCode".equals(fieldName)) { regex.setRegexCode(in.nextString()); } else if ("regexValue".equals(fieldName)) { // 直接读取原始值转为字符串,忽略默认的数组类型判定 regex.setRegexValue(in.nextString()); } else { in.skipValue(); } } in.endObject(); return regex; } @Override public void write(JsonWriter out, Regex value) throws IOException { // 序列化逻辑按需实现即可 out.beginObject(); out.name("regexCode").value(value.getRegexCode()); out.name("regexValue").value(value.getRegexValue()); out.endObject(); } }
然后构建带适配规则的Gson实例:
Gson gson = new GsonBuilder() .setLenient() // 开启宽松解析,支持无引号的属性和字符串 .registerTypeAdapter(Regex.class, new RegexAdapter()) .create(); TableDefinition tableDefinition = gson.fromJson(rawJson, TableDefinition.class);
这种方案不需要修改原始字符串,适配性更强。
内容的提问来源于stack exchange,提问作者fuat
相关产品推荐
相关产品推荐

