如何用Java GSON反序列化带引号的JSON数组至指定POJO
你可以通过为Book类的tags字段单独指定自定义反序列化器来解决这个问题,完全满足你的三个需求:
步骤1:编写自定义反序列化器
这个反序列化器会同时兼容错误的字符串格式和正常的数组格式:
import com.google.gson.*; import java.lang.reflect.Type; import java.util.Arrays; import java.util.List; public class TagListDeserializer implements JsonDeserializer<List<String>> { @Override public List<String> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { if (json.isJsonPrimitive()) { // 处理错误格式:带引号的字符串数组 String tagStr = json.getAsString(); // 去除首尾的[] String cleanedTags = tagStr.substring(1, tagStr.length() - 1); // 按逗号分割成列表(如果标签含空格可改用\\s*,\\s*分割) return Arrays.asList(cleanedTags.split(",")); } else if (json.isJsonArray()) { // 正常数组格式,使用GSON默认反序列化逻辑 return context.deserialize(json, typeOfT); } throw new JsonParseException("tags字段格式错误:既不是字符串也不是数组"); } }
步骤2:修改Book类,为tags字段绑定反序列化器
通过@JsonAdapter注解,仅让该反序列化器作用于Book类的tags字段,其他字段保持默认反序列化:
import com.google.gson.annotations.JsonAdapter; import com.google.gson.annotations.SerializedName; import lombok.Data; @Data public class Book { @SerializedName("id") private String id; @SerializedName("tags") @JsonAdapter(TagListDeserializer.class) private List<String> tags; }
步骤3:测试验证
无论是错误格式还是正确格式的JSON,都能正常反序列化:
import com.google.gson.Gson; public class TestDeserialization { public static void main(String[] args) { // 错误格式的JSON String wrongFormatJson = "{\"id\": \"B09W1W4D2F\",\"tags\": \"[TAG_1,TAG_2]\"}"; Gson gson = new Gson(); Book book1 = gson.fromJson(wrongFormatJson, Book.class); System.out.println(book1.getTags()); // 输出 [TAG_1, TAG_2] // 正确格式的JSON String correctFormatJson = "{\"id\": \"B09W1W4D2F\",\"tags\": [\"TAG_1\",\"TAG_2\"]}"; Book book2 = gson.fromJson(correctFormatJson, Book.class); System.out.println(book2.getTags()); // 输出 [TAG_1, TAG_2] } }
方案符合需求的说明
- 反序列化结果直接存入
List<String> tags字段:自定义逻辑将字符串格式的标签转换为List集合。 - 其他字段保留默认反序列化:仅tags字段添加了自定义注解,id字段仍使用GSON默认的反序列化逻辑。
- 仅作用于Book类:注解绑定在Book类的tags字段上,其他类的
List<String>字段不会受到影响。
内容的提问来源于stack exchange,提问作者a3dsfcv
相关产品推荐
相关产品推荐

