使用GSON库反序列化对象列表失败,请求技术帮助
解决Gson反序列化时"Expected BEGIN_ARRAY but was STRING"的错误
这个错误其实很明确:Gson期望解析一个JSON数组(也就是以[开头的结构),但实际拿到的是一个字符串类型的数据。结合你的代码和场景,我帮你梳理下可能的问题和解决办法:
问题根源排查
首先你要确认ser.getKeywordStats()返回的JSON字符串是否是纯粹的数组格式。很多时候出现这个错误,是因为返回的字符串被额外的双引号包裹了,或者内部的引号被转义了。比如原本的JSON数组应该是:
[{"Name": "Initialize", ...}, {...}]
但实际返回的可能是:
"[{\"Name\": \"Initialize\", ...}, {...}]"
这种情况下,Gson会把整个内容当成一个字符串,而不是数组,自然就会抛出这个错误。
另外还有一个小细节:你的模型类用了@JsonProperty注解,这是Jackson框架的注解,Gson是不识别的!虽然你的字段名和JSON的键完全一致,Gson默认能匹配上,但为了规范,建议换成Gson的@SerializedName注解。
解决步骤
1. 先确认原始JSON字符串的格式
先直接打印ser.getKeywordStats()的原始返回值,看看是不是有多余的引号或转义:
String rawJson = ser.getKeywordStats(); System.out.println("原始返回的JSON: " + rawJson);
如果输出结果前后带有双引号,或者里面的引号是\"形式,那就是问题所在,需要先处理这个字符串。
2. 修复字符串格式(如果需要)
如果原始字符串被包裹或转义,先做处理:
String rawJson = ser.getKeywordStats().trim(); // 去掉前后的双引号 if (rawJson.startsWith("\"") && rawJson.endsWith("\"")) { rawJson = rawJson.substring(1, rawJson.length() - 1); } // 把转义的引号还原成普通引号 rawJson = rawJson.replace("\\\"", "\"");
3. 调整模型类的注解(可选但推荐)
把Jackson的@JsonProperty换成Gson的@SerializedName:
import com.google.gson.annotations.SerializedName; public class KeywordDetails { public KeywordDetails() {} @SerializedName("Name") public String Name; @SerializedName("Type") public String Type; @SerializedName("Library") public String Library; @SerializedName("StartTime") public String StartTime; @SerializedName("EndTime") public String EndTime; @SerializedName("Status") public String Status; @SerializedName("ScenarioName") public String ScenarioName; @SerializedName("Environment") public String Environment; @SerializedName("ElapsedTime") public double ElapsedTime; }
4. 简化反序列化代码
其实你不需要先用JsonParser解析,Gson可以直接把字符串转换成列表,简化后的代码:
Gson gson = new Gson(); Type listType = new TypeToken<ArrayList<KeywordDetails>>() {}.getType(); String rawJson = ser.getKeywordStats().trim(); // 处理可能的字符串包裹问题 if (rawJson.startsWith("\"") && rawJson.endsWith("\"")) { rawJson = rawJson.substring(1, rawJson.length() - 1).replace("\\\"", "\""); } List<KeywordDetails> keywordDetails = gson.fromJson(rawJson, listType);
额外提示
如果处理后还是有问题,建议把处理后的rawJson打印出来,然后用本地的JSON格式化工具检查是否是合法的JSON数组格式,确保没有语法错误。
内容的提问来源于stack exchange,提问作者Saran
相关产品推荐
相关产品推荐

