android - 解析时间戳期间的 GSON 异常
问题描述
由于时间戳格式,我的应用程序无法解析 REST API 响应。REST API 返回 JSON:
{
"id": 4,
"username": "test555",
"email": "test555@test.com",
"password": "pass",
"role": "USER",
"enabled": 1,
"lastPassChange": null,
"created": [2019, 6, 16, 19, 8, 34, 843438000]
}
但是我的应用程序抛出异常,因为它期待对象但它接收数组。
我添加了实现
'com.fatboyindustrial.gson-jodatime-serialisers:gson-jodatime-serialisers:1.7.0'
并添加到我的 gson 单例中:
public class GsonSingleton {
private static GsonSingleton sInstace;
private Gson gson;
public static synchronized GsonSingleton getInstance(){
if(sInstace == null){
sInstace = new GsonSingleton();
}
return sInstace;
}
private GsonSingleton(){
this.gson = Converters.registerLocalDateTime(new GsonBuilder()).create();
}
public Gson gson(){
return this.gson;
}
public JSONObject obj2Json(Object o) throws JSONException{
return new JSONObject(gson.toJson(o));
}
}
但这无济于事。
发生异常的行:
User savedUser = GsonSingleton.getInstance().gson().fromJson(response.toString(), User.class);
异常堆栈:
`com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 191 path $.created
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:226)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:131)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:222)
at com.google.gson.Gson.fromJson(Gson.java:927)
at com.google.gson.Gson.fromJson(Gson.java:892)
at com.google.gson.Gson.fromJson(Gson.java:841)
at com.google.gson.Gson.fromJson(Gson.java:813)
at eu.blubit.autobook.view.AccountFormActivity$1.onResponse(AccountFormActivity.java:153)
at eu.blubit.autobook.view.AccountFormActivity$1.onResponse(AccountFormActivity.java:148)
at com.android.volley.toolbox.JsonRequest.deliverResponse(JsonRequest.java:90)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:102)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6816)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1563)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1451)
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 191 path $.created
at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:385)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:215)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:131)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:222)
at com.google.gson.Gson.fromJson(Gson.java:927)
at com.google.gson.Gson.fromJson(Gson.java:892)
at com.google.gson.Gson.fromJson(Gson.java:841)
at com.google.gson.Gson.fromJson(Gson.java:813)
at eu.blubit.autobook.view.AccountFormActivity$1.onResponse(AccountFormActivity.java:153)
at eu.blubit.autobook.view.AccountFormActivity$1.onResponse(AccountFormActivity.java:148)
at com.android.volley.toolbox.JsonRequest.deliverResponse(JsonRequest.java:90)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:102)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6816)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1563)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1451)`
但我应该收到 User.class 对象:
@Entity
public class User {
@PrimaryKey
@NonNull
private Long id;
@Size(min=3, max=20)
private String username;
private String email;
@Size(min=6)
private String password;
private String role;
private Integer enabled;
private LocalDateTime lastPassChange;
private LocalDateTime created;
//setters and getters
解决方案
我找到了其他适合我的方式。我在我的单例中添加了新类,它是 json 的自定义反序列化器。
public class JsonDateTimeArrayDeserializer implements JsonDeserializer<LocalDateTime>{
@Override
public LocalDateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonArray jArr = json.getAsJsonArray();
return LocalDateTime.of(jArr.get(0).getAsInt(), jArr.get(1).getAsInt(), jArr.get(2).getAsInt(), jArr.get(3).getAsInt(), jArr.get(4).getAsInt(), jArr.get(5).getAsInt(), jArr.get(6).getAsInt());
}
}
我必须在以下位置注册它private GsonSingleton()
:
this.gson = new GsonBuilder.registerTypeAdapter(LocalDateTime.class, new JsonDateTimeArrayDeserializer()).create
推荐阅读
- php - 如何更改我的代码以将我的第二张照片包含在我的轮播中?
- angular - formBuilder.group({}) 中的调用函数
- windows - OpenH264 解码与网络延迟导致失败
- javascript - 如何获取被点击事件的具体日期
- android - 使用回收站视图时如何取回选择了哪个单选按钮的数据
- javascript - 如何使用 ES6 模块导入惰性加载和同位素?
- php - 从服务器(下载服务器或 s3 或任何云服务器)下载流文件的最佳方法是什么?
- mysql - MySQL:如何将大型数据表(近 800 亿行)分解为多个表
- java - Swagger:为特定@Api路径下的所有请求定义通用参数
- java - 如何使用 iText 读取 PDF 文件作为模板