Retrofit获取GpsCordinates列表时触发JsonSyntaxException求助
问题分析与解决方案
这个JsonSyntaxException的根源很明确:Gson默认无法将服务器返回的毫秒级时间戳数字直接转换为Java的Date对象。服务器返回的date字段是1516532556000这种长整型的时间戳,但Gson默认的Date解析逻辑是处理字符串格式的日期(比如"2024-05-20T12:00:00"),所以遇到数字类型的时间戳就会抛出语法错误。
下面给你两种可行的解决方式,任选其一即可:
方法一:为Date字段添加自定义解析适配器
这种方式只针对单个实体类的Date字段生效,适合局部调整的场景:
- 首先创建一个自定义的
TypeAdapter,用来处理时间戳和Date的互转:
import com.google.gson.TypeAdapter; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; import com.google.gson.stream.JsonWriter; import java.io.IOException; import java.util.Date; public class TimestampDateAdapter extends TypeAdapter<Date> { @Override public void write(JsonWriter out, Date value) throws IOException { if (value == null) { out.nullValue(); return; } // 序列化时把Date转成时间戳 out.value(value.getTime()); } @Override public Date read(JsonReader in) throws IOException { if (in.peek() == JsonToken.NULL) { in.nextNull(); return null; } // 解析时把时间戳转成Date return new Date(in.nextLong()); } }
- 然后在
GpsCordinates类的date字段上添加@JsonAdapter注解,指定用这个适配器来解析:
import com.google.gson.annotations.Expose; import com.google.gson.annotations.JsonAdapter; import com.google.gson.annotations.SerializedName; import java.util.Date; public class GpsCordinates { @SerializedName("x") @Expose private double x; @SerializedName("y") @Expose private double y; @SerializedName("date") @Expose @JsonAdapter(TimestampDateAdapter.class) // 新增这行注解 private Date date; // 省略getter和setter方法 }
方法二:全局配置Gson处理时间戳
如果你的项目中有很多地方需要解析时间戳转Date,这种全局配置的方式更高效:
在构建Retrofit实例的时候,传入一个已经配置好时间戳解析规则的Gson对象:
import com.google.gson.Gson; import com.google.gson.GsonBuilder; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; // 创建自定义Gson实例 Gson gson = new GsonBuilder() .registerTypeAdapter(Date.class, new TimestampDateAdapter()) .create(); // 构建Retrofit时使用这个Gson Retrofit retrofit = new Retrofit.Builder() .baseUrl("你的服务器基础地址") .addConverterFactory(GsonConverterFactory.create(gson)) .build(); Api api = retrofit.create(Api.class);
注意事项
- 你的服务器返回的是毫秒级时间戳,所以直接用
new Date(in.nextLong())就可以;如果是秒级时间戳,需要改成new Date(in.nextLong() * 1000)。 - 确保你已经添加了Gson的依赖,Retrofit的GsonConverterFactory依赖于Gson库。
内容的提问来源于stack exchange,提问作者Nikolay Romanov
相关产品推荐
相关产品推荐

