Gson反序列化JSON时提示Expected BEGIN_OBJECT but was STRING错误如何解决
问题原因
报错是因为Gson默认没有内置org.json.JSONArray类型的反序列化适配器,无法直接将JSON字符串数组映射为该类型的实例,才会抛出类型不匹配异常。
解决方案
方案1:修改实体类字段类型(最推荐,无额外代码)
直接将def字段改为Gson原生支持的类型即可,无需调整反序列化逻辑:
public class HandleConfig{ @SerializedName("visible") private int visible; @SerializedName("clear") private int clear; @SerializedName("mandatory") private int mandatory; // 可选1:改为List<String>,业务取值更方便 @SerializedName("default") private List<String> def; // 可选2:如果需要用JSON数组类型,改用Gson自带的com.google.gson.JsonArray // @SerializedName("default") // private JsonArray def; // 此处省略getter和setter方法 }
修改后直接用原有反序列化代码即可正常解析。
方案2:注册自定义反序列化适配器(适配必须使用org.json.JSONArray的场景)
如果业务逻辑强制要求字段为org.json.JSONArray类型,可通过自定义TypeAdapter让Gson支持该类型的反序列化:
- 首先实现自定义适配器:
import com.google.gson.TypeAdapter; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; import org.json.JSONArray; import org.json.JSONException; import java.io.IOException; public class OrgJsonArrayTypeAdapter extends TypeAdapter<JSONArray> { @Override public void write(JsonWriter out, JSONArray value) throws IOException { out.value(value.toString()); } @Override public JSONArray read(JsonReader in) throws IOException { StringBuilder jsonSb = new StringBuilder("["); in.beginArray(); boolean firstItem = true; while (in.hasNext()) { if (!firstItem) { jsonSb.append(","); } firstItem = false; // 直接读取字符串元素,如有其他类型需求可扩展判断逻辑 jsonSb.append("\"").append(in.nextString()).append("\""); } in.endArray(); jsonSb.append("]"); try { return new JSONArray(jsonSb.toString()); } catch (JSONException e) { throw new IOException("JSONArray解析失败", e); } } }
- 初始化Gson时注册适配器,原有反序列化逻辑保持不变:
Gson gson1 = new GsonBuilder() .registerTypeAdapter(JSONArray.class, new OrgJsonArrayTypeAdapter()) .create(); Type collectionType1 = new TypeToken<List<HandleConfig>>(){}.getType(); List<HandleConfig> handleConfigurations = gson1.fromJson(object.toString(), collectionType1);
内容的提问来源于stack exchange,提问作者Mahesh Gouda
相关产品推荐
相关产品推荐

