You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:55:23