如何用Gson/Retrofit将带点分隔注解的Java POJO序列化为嵌套JSON
解决方案:基于Gson自定义序列化器实现嵌套JSON生成
你可以通过实现自定义Gson JsonSerializer,结合你已有的convertToObj函数,实现将带点分隔@SerializedName的Java类序列化为嵌套JSON的需求。以下是完整实现步骤:
1. 实现自定义序列化器
这个序列化器会遍历类的所有字段,读取@SerializedName标注的键和字段值,将点分隔键转换为嵌套Map并合并,最终生成目标JSON。
import com.google.gson.*; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; public class InputDataSerializer implements JsonSerializer<InputData> { @Override public JsonElement serialize(InputData src, java.lang.reflect.Type typeOfSrc, JsonSerializationContext context) { Map<String, Object> rootMap = new HashMap<>(); for (Field field : src.getClass().getDeclaredFields()) { try { field.setAccessible(true); Object fieldValue = field.get(src); if (fieldValue == null) continue; // 获取序列化键:优先用@SerializedName,否则用字段名 SerializedName serializedName = field.getAnnotation(SerializedName.class); String targetKey = serializedName != null ? serializedName.value() : field.getName(); // 生成当前字段的嵌套Map Map<String, Object> fieldNestedMap = convertToObj(targetKey, fieldValue.toString()); // 合并到根Map(处理同前缀的嵌套结构) mergeNestedMaps(rootMap, fieldNestedMap); } catch (IllegalAccessException e) { e.printStackTrace(); } } return context.serialize(rootMap); } // 合并两个嵌套Map,处理层级结构 private void mergeNestedMaps(Map<String, Object> destMap, Map<String, Object> srcMap) { for (Map.Entry<String, Object> entry : srcMap.entrySet()) { String key = entry.getKey(); Object srcValue = entry.getValue(); Object destValue = destMap.get(key); if (destValue instanceof Map && srcValue instanceof Map) { // 递归合并子Map mergeNestedMaps((Map<String, Object>) destValue, (Map<String, Object>) srcValue); } else { destMap.put(key, srcValue); } } } // 你已有的键转嵌套Map函数 private static HashMap<String, Object> convertToObj(String key, String value) { HashMap<String, Object> root = new HashMap<>(); Map<String, Object> currentMap = root; String[] keyParts = key.split("\\."); for (int i = 0; i < keyParts.length; i++) { String part = keyParts[i]; if (i == keyParts.length - 1) { currentMap.put(part, value); } else { Map<String, Object> subMap = (Map<String, Object>) currentMap.get(part); if (subMap == null) { subMap = new HashMap<>(); currentMap.put(part, subMap); } currentMap = subMap; } } return root; } }
2. 使用Gson序列化InputData
创建Gson实例时注册自定义序列化器,即可生成期望的嵌套JSON:
public class SerializationDemo { public static void main(String[] args) { InputData input = new InputData(); Gson gson = new GsonBuilder() .registerTypeAdapter(InputData.class, new InputDataSerializer()) .setPrettyPrinting() // 可选:格式化输出JSON .create(); String nestedJson = gson.toJson(input); System.out.println(nestedJson); } }
3. 适配Retrofit
如果需要在Retrofit中使用,只需将上述Gson实例传入GsonConverterFactory:
Retrofit retrofit = new Retrofit.Builder() .baseUrl("your_api_base_url") .addConverterFactory(GsonConverterFactory.create(gson)) .build();
效果验证
运行上述代码后,会输出你期望的嵌套JSON结构:
{ "type": "Usage", "timeframe": "custom", "timePeriod": { "from": "2022-07-14T00:00:00+00:00", "to": "2022-07-26T23:59:59+00:00" } }
内容的提问来源于stack exchange,提问作者abdulH
相关产品推荐
相关产品推荐

