You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将格式错误的JSON数组字符串转换为Java对象的方法

解析格式错误的JSON为Java对象的解决方案

我从API拿到了一段格式有问题的JSON数组字符串,具体是ResponseMsg属性值的左方括号前多了个双引号,导致整个JSON结构不合法:

[{"ResponseCode":1,"ResponseMsg":"[{"Code":"CA2305181","Message":"Processed successfully"}]"}]

我试过用Jackson解析,代码如下:

ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(new ResponseNameStrategy());
Response[] response = mapper.readValue(strOutput1, Response[].class);

结果报错:Error: Can not deserialize instance of java.util.ArrayList out of VALUE_STRING token

也尝试过Gson解析:

Gson gson = new GsonBuilder()
    .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
    .create();
Response[] response = gson.fromJson(strOutput1, Response[].class);

报错信息是:Error: Expected BEGIN_ARRAY but was STRING at line 1 column 35 path $[0].ResponseMsg

我查了不少相关问题,但都没解决我的问题。


解决方案思路

因为原始JSON本身是格式不合法的,所以第一步必须先修复这个JSON的格式问题,再进行解析。这里的核心问题是ResponseMsg的值被错误地用双引号包裹成了字符串,实际上它应该是一个JSON数组。

方法一:手动修复字符串(适合固定格式的场景)

如果API返回的错误格式是固定的(比如总是在ResponseMsg的[前多双引号、结尾多双引号),可以先用字符串替换快速修正:

// 修正格式错误:去掉ResponseMsg值前后的多余双引号
String fixedJson = strOutput1.replace("\"[{\"", "[{\"").replace("\"}]\"", "}]");
// 之后再用Jackson或Gson解析修正后的fixedJson

方法二:自定义反序列化器(更灵活的通用方案)

如果错误格式有变化,或者不想依赖硬编码的字符串替换,可以自定义反序列化逻辑,告诉解析器把ResponseMsg的字符串内容当作JSON数组来解析。

用Jackson实现自定义反序列化

假设你的实体类结构是这样的:

public class Response {
    private int ResponseCode;
    private List<ResponseDetail> ResponseMsg;
    // getter、setter、构造方法
}

public class ResponseDetail {
    private String Code;
    private String Message;
    // getter、setter、构造方法
}

编写自定义反序列化器:

public class ResponseMsgDeserializer extends JsonDeserializer<List<ResponseDetail>> {
    @Override
    public List<ResponseDetail> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        // 获取ResponseMsg的字符串内容
        String msgStr = p.getText();
        // 去掉前后多余的双引号
        msgStr = msgStr.replaceAll("^\"|\"$", "");
        // 将处理后的字符串解析为List
        ObjectMapper mapper = new ObjectMapper();
        return mapper.readValue(msgStr, new TypeReference<List<ResponseDetail>>() {});
    }
}

然后在Response类的ResponseMsg字段上添加注解,指定使用自定义反序列化器:

public class Response {
    private int ResponseCode;
    @JsonDeserialize(using = ResponseMsgDeserializer.class)
    private List<ResponseDetail> ResponseMsg;
    // ...
}

之后再用Jackson解析原始JSON字符串就能正常工作了。

用Gson实现自定义反序列化

同样基于上述实体类,编写Gson的自定义反序列化器:

public class ResponseMsgDeserializer implements JsonDeserializer<List<ResponseDetail>> {
    @Override
    public List<ResponseDetail> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        String msgStr = json.getAsString();
        // 去掉前后多余的双引号
        msgStr = msgStr.replaceAll("^\"|\"$", "");
        // 将处理后的字符串解析为List
        return new Gson().fromJson(msgStr, typeOfT);
    }
}

注册反序列化器后再解析:

Gson gson = new GsonBuilder()
    .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
    .registerTypeAdapter(new TypeToken<List<ResponseDetail>>(){}.getType(), new ResponseMsgDeserializer())
    .create();
Response[] response = gson.fromJson(strOutput1, Response[].class);

内容的提问来源于stack exchange,提问作者A_J

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:40:14