如何实现自定义GsonConverterFactory/JsonDeserializer处理动态类型?
解决方法:自定义JsonDeserializer处理动态类型字段
这个问题我之前也碰到过,Gson默认确实处理不了这种一会儿是数组、一会儿是布尔值的动态字段,不过自定义一个JsonDeserializer就能轻松搞定~
步骤1:定义Tag实体类
先把对应JSON字段的Tag实体类写好:
public class Tag { @SerializedName("content_id") private String contentId; @SerializedName("tag_id") private String tagId; private String created; @SerializedName("tag_name") private String tagName; // 按需添加构造方法、getter/setter }
步骤2:编写自定义JsonDeserializer
创建一个实现JsonDeserializer<List<Tag>>的类,专门处理tags字段的两种情况:
public class TagsDeserializer implements JsonDeserializer<List<Tag>> { @Override public List<Tag> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { // 先判断JSON元素的类型 if (json.isJsonArray()) { // 是数组的话,正常解析成List<Tag> return context.deserialize(json, typeOfT); } else if (json.isJsonPrimitive()) { JsonPrimitive primitive = json.getAsJsonPrimitive(); // 是布尔值且为false时,返回null(按你的需求来) if (primitive.isBoolean() && !primitive.getAsBoolean()) { return null; } } // 其他异常情况(比如tags是true/字符串等),可以抛出异常或返回默认值 throw new JsonParseException("Unexpected type for tags field: " + json.getClass().getName()); } }
步骤3:注册反序列化器并创建GsonConverterFactory
把自定义的反序列化器注册到Gson实例中,再用它生成Retrofit需要的GsonConverterFactory:
// 构建带自定义规则的Gson实例 Gson gson = new GsonBuilder() .registerTypeAdapter(new TypeToken<List<Tag>>(){}.getType(), new TagsDeserializer()) .create(); // 初始化Retrofit时使用这个Gson Retrofit retrofit = new Retrofit.Builder() .baseUrl("你的接口基础地址") .addConverterFactory(GsonConverterFactory.create(gson)) // 其他配置(如OkHttpClient) .build();
补充说明
- 如果
tags字段是嵌套在其他实体类(比如Article)里,只要Article中tags字段定义为List<Tag>,Gson就会自动调用我们的自定义反序列化器处理。 - 要是你希望空值时返回空列表而非null,把代码里的
return null改成return Collections.emptyList()即可。 - 对于其他异常输入(比如tags是true或字符串),可以根据业务需求调整逻辑,比如返回null或者抛出更明确的提示。
内容的提问来源于stack exchange,提问作者Dale Julian
相关产品推荐
相关产品推荐

