如何用Gson为对象添加新键值对并序列化为JSON?
给Gson序列化的对象追加String键值对的实用方案
嘿,这个需求太常见了!不用重构原有对象、不用写一堆重复的样板代码,Gson有几种灵活的方式能帮你实现,我给你列几个最实用的:
方案一:直接合并JsonObject(最适合临时场景)
这个方法最简单直接——先把原有对象序列化成JsonObject,然后直接往里面塞额外的键值对,最后转成JSON字符串就行。
示例代码:
// 假设你的原有实体类是这样的 public class MyObject { private String name; private Float price; private LocalDate createDate; // 构造器、getter/setter 这里省略 } // 初始化Gson,记得适配LocalDate(Gson原生不支持Java8日期类型) Gson gson = new GsonBuilder() .registerTypeAdapter(LocalDate.class, new LocalDateAdapter()) .create(); // 实例化你的对象 MyObject myObj = new MyObject("奶茶", 15.9f, LocalDate.now()); // 第一步:把原有对象转成JsonObject JsonObject jsonObject = gson.toJsonTree(myObj).getAsJsonObject(); // 第二步:添加你的String键值对 jsonObject.addProperty("shopName", "街角奶茶铺"); jsonObject.addProperty("promotion", "第二杯半价"); // 第三步:转成最终的JSON字符串 String finalJson = gson.toJson(jsonObject);
补充:LocalDate的适配器写法
因为Gson默认不支持Java 8的LocalDate,所以需要自定义一个序列化适配器:
class LocalDateAdapter implements JsonSerializer<LocalDate> { @Override public JsonElement serialize(LocalDate src, Type typeOfSrc, JsonSerializationContext context) { // 这里用ISO标准格式,你也可以换成自己需要的格式 return new JsonPrimitive(src.format(DateTimeFormatter.ISO_LOCAL_DATE)); } }
方案二:自定义JsonSerializer(适合复用场景)
如果你的项目里多个地方都需要给对象追加额外键值对,或者需要统一管理这些额外字段,那自定义一个通用的序列化器会更方便。
示例代码:
// 通用的额外字段序列化器 public class ExtraFieldsSerializer<T> implements JsonSerializer<T> { private final Map<String, String> extraFields; private final JsonSerializer<T> delegateSerializer; // 构造器传入要追加的键值对,以及原有对象的默认序列化器 public ExtraFieldsSerializer(Map<String, String> extraFields, JsonSerializer<T> delegateSerializer) { this.extraFields = extraFields; this.delegateSerializer = delegateSerializer; } @Override public JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context) { // 先让默认序列化器处理原有对象 JsonElement jsonElement = delegateSerializer.serialize(src, typeOfSrc, context); // 如果是JsonObject类型,就追加额外字段 if (jsonElement.isJsonObject()) { JsonObject jsonObj = jsonElement.getAsJsonObject(); extraFields.forEach(jsonObj::addProperty); } return jsonElement; } }
使用方式:
// 准备要追加的键值对 Map<String, String> extraPairs = new HashMap<>(); extraPairs.put("orderId", "OD20240520001"); extraPairs.put("deliveryTime", "30分钟内"); // 初始化Gson时注册自定义序列化器 Gson gson = new GsonBuilder() .registerTypeAdapter(LocalDate.class, new LocalDateAdapter()) .registerTypeAdapter(MyObject.class, new ExtraFieldsSerializer<>(extraPairs, new Gson().getAdapter(MyObject.class))) .create(); // 直接序列化原有对象,会自动追加额外字段 String finalJson = gson.toJson(myObj);
注意点
- 如果原有对象中已经存在和额外字段同名的属性,新添加的键值对会覆盖原有值,这点要留意。
- 如果你用的是Gson 2.8及以上版本,优先用
toJsonTree转JsonObject的方式,比旧的JsonParser更高效。
内容的提问来源于stack exchange,提问作者gabriel119435
相关产品推荐
相关产品推荐

