使用Gson解析输入负载时如何忽略类型不匹配问题
解决Gson解析时类型不匹配的问题
你的Site类中switchMgmt字段定义为Map<String, Object>,但用户提交的JSON里该字段是空字符串,Gson无法将字符串直接转为Map,因此抛出Expected BEGIN_OBJECT but was STRING的异常。要处理这种用户输入不可控的情况,可以通过自定义反序列化逻辑来解决:
方案一:全局注册Map类型的自定义反序列化器
编写一个自定义的JsonDeserializer,当遇到字符串类型的输入时,返回null或者空Map,正常情况按默认逻辑解析:
public class MapTypeDeserializer implements JsonDeserializer<Map<String, Object>> { @Override public Map<String, Object> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { // 若输入是字符串,空字符串则返回null(也可改为返回new HashMap<>()) if (json.isJsonPrimitive() && json.getAsJsonPrimitive().isString()) { return json.getAsString().isEmpty() ? null : null; } // 正常对象类型按默认方式解析 return context.deserialize(json, typeOfT); } }
创建Gson实例时注册该反序列化器:
Gson gson = new GsonBuilder() .registerTypeAdapter(new TypeToken<Map<String, Object>>(){}.getType(), new MapTypeDeserializer()) .create(); Site data = gson.fromJson(jsonString, Site.class);
方案二:仅针对switchMgmt字段配置反序列化器
如果不想全局修改Map的解析逻辑,可以直接在switchMgmt字段上添加@JsonAdapter注解,指定自定义反序列化器:
public class Site { @JsonProperty("id") String id; @JsonProperty("name") String name; @SerializedName("switch_mgmt") @JsonAdapter(MapTypeDeserializer.class) Map<String, Object> switchMgmt; }
之后正常创建Gson实例即可解析,无需全局注册。
内容的提问来源于stack exchange,提问作者iceyb
相关产品推荐
相关产品推荐

