使用Retrofit解析LocalDate时触发java.lang.IllegalStateException异常:预期BEGIN_OBJECT却为STRING
问题分析与解决
这个错误java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING的核心原因很明确:
Gson默认不知道如何处理LocalDate类型,它会把这个类型当作JSON对象去解析,但你的接口返回的fecha_alta字段实际是一个日期字符串(比如"15/03/2024"),两者不匹配就触发了异常。
而你虽然已经写了LocalDate的反序列化适配器,但你的Retrofit实例根本没用到这个配置好的Gson!看你的调用代码:
apiService = Network.getInstance().create(ApiService.class);
你这里用的是Network类的Retrofit单例,而不是你自己写的Client.getClient()创建的实例——也就是说,当前Retrofit用的是默认的GsonConverterFactory,完全没加载你写的LocalDate解析逻辑。
解决方法
方法1:改用你自己的Client类创建Retrofit实例
直接修改调用代码里的apiService初始化逻辑,替换成你配置好Gson的Client类:
// 替换BASE_URL为你的接口实际基础地址 apiService = Client.getClient(BASE_URL).create(ApiService.class);
方法2:将LocalDate解析配置整合到Network单例中
如果你的项目是用Network类统一管理Retrofit单例,更合理的做法是把Gson配置移到这个类里,确保所有请求都能用同一个正确配置的Gson:
public class Network { private static Retrofit retrofit; // 替换成你的实际接口基础地址 private static final String BASE_URL = "https://your-api-domain.com/"; public static Retrofit getInstance() { if (retrofit == null) { // 配置支持LocalDate的Gson Gson gson = new GsonBuilder() .registerTypeAdapter(LocalDate.class, new JsonDeserializer<LocalDate>() { @Override public LocalDate deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException { // 确保这里的日期格式和接口返回的完全一致 return LocalDate.parse(json.getAsString(), DateTimeFormatter.ofPattern("dd/MM/yyyy")); } }) .create(); retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create(gson)) .build(); } return retrofit; } }
这样你的原有调用代码不用修改,就能正常解析LocalDate类型了。
额外注意事项
一定要确认DateTimeFormatter.ofPattern("dd/MM/yyyy")的格式和接口返回的日期字符串完全匹配,比如如果接口返回的是2024-03-15,你就要把格式改成yyyy-MM-dd,否则会触发新的解析异常。
内容的提问来源于stack exchange,提问作者ProFra
相关产品推荐
相关产品推荐

