使用Retrofit请求时,如何获取MongoDB返回响应中的$date字段?
嘿,这个场景我太熟悉了!MongoDB返回的日期格式带个$date字段,用Retrofit解析的时候确实容易因为这个特殊符号卡壳,给你几个靠谱的解决办法:
方案1:用序列化注解直接映射(最省心)
不管你用Gson还是Moshi这类序列化库,都可以通过注解把带$的特殊字段映射到实体类的属性上——毕竟直接写$date当属性名在Java/Kotlin里是不合法的。
如果你用Gson:
在实体类的日期属性上加上@SerializedName("$date")注解就行,示例代码:
public class YourResponse { // 其他业务字段... @SerializedName("$date") private long timestamp; // MongoDB的$date通常存毫秒级时间戳 // 也可以直接映射成Date对象: // @SerializedName("$date") // private Date createTime; // 别忘了写getter/setter }
这样Gson会自动把响应里的"$date": 1620000000000映射到你的属性中。
如果你用Moshi:
用@Json(name = "$date")注解替代,Kotlin示例:
data class YourResponse( // 其他业务字段... @Json(name = "$date") val timestamp: Long, // 或者直接转成LocalDateTime: // @Json(name = "$date") // val createTime: LocalDateTime )
Moshi同样能识别这个特殊字段名,完美适配。
方案2:自定义类型转换器(处理复杂日期格式)
如果你的$date返回的不是纯时间戳,而是ISO格式的字符串(比如"$date": "2024-05-20T12:00:00Z"),或者你想统一处理所有日期字段的解析逻辑,可以自定义类型转换器。
比如用Gson写一个DateTypeAdapter:
public class DateTypeAdapter extends TypeAdapter<Date> { @Override public void write(JsonWriter out, Date value) throws IOException { out.value(value.getTime()); } @Override public Date read(JsonReader in) throws IOException { in.beginObject(); long timestamp = 0; while (in.hasNext()) { if ("$date".equals(in.nextName())) { // 如果是字符串格式,就用in.nextString()再解析成时间戳 timestamp = in.nextLong(); } else { in.skipValue(); // 跳过其他无关字段 } } in.endObject(); return new Date(timestamp); } }
然后把这个适配器注册到Gson实例,再传给Retrofit:
// 初始化带自定义适配器的Gson Gson customGson = new GsonBuilder() .registerTypeAdapter(Date.class, new DateTypeAdapter()) .create(); // 构建Retrofit时使用这个Gson Retrofit retrofit = new Retrofit.Builder() .baseUrl("你的接口地址") .addConverterFactory(GsonConverterFactory.create(customGson)) .build();
方案3:手动解析响应(应急方案)
如果临时不想改实体类或者转换器,也可以先把响应转换成JsonObject,手动提取$date的值:
Gson示例:
Call<ResponseBody> call = yourApiService.fetchData(); call.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { if (response.isSuccessful() && response.body() != null) { try { String responseJson = response.body().string(); JsonObject rootObj = new Gson().fromJson(responseJson, JsonObject.class); // 假设日期字段是嵌套在某个键下,比如"createTime" JsonObject dateObj = rootObj.getAsJsonObject("createTime"); long timestamp = dateObj.get("$date").getAsLong(); // 如果是字符串格式就用getAsString() // String dateStr = dateObj.get("$date").getAsString(); // 后续处理时间戳/日期字符串 } catch (IOException e) { e.printStackTrace(); } } } @Override public void onFailure(Call<ResponseBody> call, Throwable t) { t.printStackTrace(); } });
内容的提问来源于stack exchange,提问作者Dude
相关产品推荐
相关产品推荐

