Retrofit2嵌套JSON解析:如何解析milliseconds字段?
使用Retrofit解析API响应中的milliseconds字段
首先直接回应你的问题:不推荐用@SerializedName("milliseconds") private String milliseconds;这种写法——虽然语法上能跑通,但这个字段本质是长整型的毫秒数,用String存储完全没必要,后续转成日期还得多一步类型转换,反而容易出问题。
下面给你两种实用的实现方案,按需选择:
方案一:分步解析,手动转换日期
这种方式最直观,先把API响应的结构完整映射成实体类,再把毫秒数转成Date对象赋值给你的News类。
- 先定义对应
publicationDate的实体类:
public class PublicationDate { @SerializedName("milliseconds") private long milliseconds; // 用long类型匹配数值型的毫秒数 // 生成Getter方法 public long getMilliseconds() { return milliseconds; } }
- 定义API返回的整体响应实体类:
public class NewsApiResponse { @SerializedName("payload") private List<NewsApiItem> payload; // Getter public List<NewsApiItem> getPayload() { return payload; } // 内部类对应每个新闻条目 public static class NewsApiItem { @SerializedName("id") private String id; @SerializedName("text") private String text; @SerializedName("publicationDate") private PublicationDate publicationDate; // 生成所有Getter方法 public String getId() { return id; } public String getText() { return text; } public PublicationDate getPublicationDate() { return publicationDate; } } }
- 拿到响应后转换为你的
News类:
当你通过Retrofit拿到NewsApiResponse后,就可以把每个NewsApiItem转换成你自己的News对象:
// 假设已经获取到apiResponse for (NewsApiItem apiItem : apiResponse.getPayload()) { News news = new News(); news.setText(apiItem.getText()); // 把毫秒数转成Date对象 long millis = apiItem.getPublicationDate().getMilliseconds(); news.setDate(new Date(millis)); // 后续处理这个news对象 }
方案二:用Gson自定义TypeAdapter,自动转换日期
如果不想手动处理转换,可以给Gson加一个自定义的TypeAdapter,让它直接把publicationDate节点转换成Date对象,一步到位。
- 写一个自定义的TypeAdapter:
public class DateMillisAdapter extends TypeAdapter<Date> { @Override public void write(JsonWriter out, Date value) throws IOException { if (value == null) { out.nullValue(); return; } out.value(value.getTime()); } @Override public Date read(JsonReader in) throws IOException { if (in.peek() == JsonToken.NULL) { in.nextNull(); return null; } // 解析publicationDate对象里的milliseconds字段 in.beginObject(); long millis = 0; while (in.hasNext()) { String name = in.nextName(); if ("milliseconds".equals(name)) { millis = in.nextLong(); } else { in.skipValue(); // 跳过其他无关字段 } } in.endObject(); return new Date(millis); } }
- 配置Retrofit使用这个Gson适配器:
创建Retrofit实例的时候,把自定义的TypeAdapter注册到Gson里:
Gson customGson = new GsonBuilder() .registerTypeAdapter(Date.class, new DateMillisAdapter()) .create(); Retrofit retrofit = new Retrofit.Builder() .baseUrl("你的API基础地址") .addConverterFactory(GsonConverterFactory.create(customGson)) .build();
- 简化实体类定义:
这时候你的NewsApiItem可以直接把publicationDate定义成Date类型,Gson会自动帮你完成转换:
public static class NewsApiItem { @SerializedName("id") private String id; @SerializedName("text") private String text; @SerializedName("publicationDate") private Date publicationDate; // 直接用Date类型 // Getter方法 public String getId() { return id; } public String getText() { return text; } public Date getPublicationDate() { return publicationDate; } }
之后转换News类就更简单了:
for (NewsApiItem apiItem : apiResponse.getPayload()) { News news = new News(); news.setText(apiItem.getText()); news.setDate(apiItem.getPublicationDate()); // 直接赋值Date对象 }
总结
- 不要用String存储milliseconds,用long类型更贴合字段本质
- 追求简单直接选方案一,追求自动化简化代码选方案二,两种方式都能完美解析你要的毫秒数并转换成
News类的date字段
内容的提问来源于stack exchange,提问作者flex_grigorowicz
相关产品推荐
相关产品推荐

