Android Retrofit日期解析失败求助:无法解析"2018-05-09"格式
问题原因分析
你遇到的OnErrorNotImplementedException本质上是由ParseException引发的——Retrofit在解析JSON响应里的startConnection字段时,没法把字符串"2018-05-09"转换成Date类型。
具体来说,默认情况下(假设你用Gson作为Retrofit的JSON转换器),Gson解析Date类型依赖JDK默认的日期格式(一般是EEE MMM dd HH:mm:ss zzz yyyy这种带时间、时区的格式),但接口返回的是yyyy-MM-dd这种简化的日期格式,两者不匹配,所以抛出了解析异常。
另外,你的RxJava订阅只写了成功回调的Consumer,没处理错误回调,这也是最终抛出OnErrorNotImplementedException的原因——RxJava要求必须处理订阅过程中产生的错误,不然就会触发这个未实现错误的异常。
解决方案
下面是几种常用的解决办法,你可以根据自己用的JSON转换器选择:
方法一:自定义Gson日期格式(适用于Gson转换器)
如果用的是Gson,你需要创建一个自定义的Gson实例,指定日期解析格式,再把它配置到Retrofit中:
// 创建自定义Gson实例,匹配接口返回的日期格式 Gson gson = new GsonBuilder() .setDateFormat("yyyy-MM-dd") .create(); // 配置Retrofit时使用这个自定义Gson Retrofit retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create(gson)) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build();
方法二:用注解指定单个字段的日期格式
如果你不想全局修改日期格式,只想给startConnection单独配置,可以用注解:
若使用Gson(需Gson 2.8+):
public class Device { private int id; private int phoneNumber; private String connectionName; private String deviceName; @DateFormat("yyyy-MM-dd") // 给该字段指定解析格式 private Date startConnection; private Location actualLocation; private User owner; // getters、setters和构造方法 }
若使用Jackson:
public class Device { private int id; private int phoneNumber; private String connectionName; private String deviceName; @JsonFormat(pattern = "yyyy-MM-dd") private Date startConnection; private Location actualLocation; private User owner; // getters、setters和构造方法 }
别忘了处理RxJava的错误回调
最后修改你的订阅代码,加上错误处理逻辑,避免再抛出OnErrorNotImplementedException:
public void getAllDevicesForCurrentUser(){ compositeDisposable.add(restAPI.getDevices("Bearer " + TokenHolder.getInstance().getToken()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Consumer<List<Device>>() { @Override public void accept(List<Device> devices) throws Exception { initializeDevices(devices); } }, new Consumer<Throwable>() { // 添加错误处理回调 @Override public void accept(Throwable throwable) throws Exception { // 这里可以打印日志、显示错误提示等 throwable.printStackTrace(); } })); }
内容的提问来源于stack exchange,提问作者Bartosz20188
相关产品推荐
相关产品推荐

