我有一个问题。我有以下JSON:
[
{
"Id":"8",
"MasterAgentId":"0",
"LastAgentStrategyId":"16116488969159",
"BotState":"Active",
"Owner":"Andre",
"ExtraNotifiers":"",
"Exchange":"lava",
"DateTime":"2021-01-27 22:12:02",
"AgentStatus":"Enabled",
"ProtectiveOrdersEnabled":"yes",
"Sim_Progress":"100",
"Sim_DateTime":"2021-01-27 09:18:00",
"Sim_Coin":"BTC",
"Sim_Price":"31626.580000",
"Sim_Profit":"1216.04",
"Sim_Profit_Perc":"60.80",
"Sim_StartDateTime":"2019-01-01 00:00:00",
"LastAgentStrategyRun":"2020-12-19 17:40:30.531000"
}
]
如您所见,我在JSON中有4个DateTime:DateTime, Sim_DateTime, Sim_StartDateTime, LastAgentStrategyRun
现在我创建了一个类,如下所示:
import java.time.LocalDateTime;
public class Agent {
private int Id;
private int MasterAgentId;
private long LastAgentStrategyId;
private AgentBotState BotState;
private String Owner;
private String ExtraNotifiers;
private AgentExchanges Exchange;
private LocalDateTime DateTime;
private AgentStatus AgentStatus;
private String ProtectiveOrdersEnabled;
private String Sim_Progress;
private String Sim_DateTime;
private String Sim_Coin;
private double Sim_Price;
private double Sim_Profit;
private double Sim_Profit_Perc;
private LocalDateTime Sim_StartDateTime;
private LocalDateTime LastAgentStrategyRun;
}
但是当我使用GSON反序列化json时:
Gson gson = new Gson();
Type listType = new TypeToken<ArrayList<Agent>>() {}.getType();
ArrayList<Agent> agentList = new Gson().fromJson(jsonResponse, listType);
出现以下错误:
但是代码崩溃并出现以下错误:
Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 157 path $[0].DateTime
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:200)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:103)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:196)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:81)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:60)
at com.google.gson.Gson.fromJson(Gson.java:810)
at com.google.gson.Gson.fromJson(Gson.java:775)
at com.google.gson.Gson.fromJson(Gson.java:724)
at com.company.Main.main(Main.java:34)
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 157 path $[0].DateTime
at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:387)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:189)
... 9 more
现在,当我从json中删除所有datetime时,它可以正确地解析,只有一些奇怪的警告:
警告:发生了非法的反射访问操作警告:非法的反射访问,由com.google.gson.internal.bind.反射类型适配器工厂(文件:/C:/Users/Alexander/. m2/repository/com/google/code/gson/gson/2.3.1/gson-2.3.1.jar)到字段java.time.LocalDateTime.date警告:请考虑向com.google.gson.internal.bind.反射类型适配器工厂的维护者报告此问题警告:使用--illegal-access=warn启用进一步非法反射访问操作的警告警告警告:在将来的版本中,将拒绝所有非法访问操作
如何将日期时间字符串解析为对象,以及如何消除警告?
更新
使用下面的代码:
Gson gson = new GsonBuilder().registerTypeAdapter(LocalDateTime.class, (JsonDeserializer<LocalDateTime>) (json, type, jsonDeserializationContext) -> {
Instant instant = Instant.ofEpochMilli(json.getAsJsonPrimitive().getAsLong());
return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
}).create();
Type listType = new TypeToken<ArrayList<Agent>>() {}.getType();
ArrayList<Agent> agentList = gson.fromJson(jsonResponse, listType);
我现在得到这个错误:
Exception in thread "main" java.lang.NumberFormatException: For input string: "2021-01-27 22:56:01"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:68)
at java.base/java.lang.Long.parseLong(Long.java:707)
at java.base/java.lang.Long.parseLong(Long.java:832)
at com.google.gson.JsonPrimitive.getAsLong(JsonPrimitive.java:238)
at com.company.Main.lambda$main$0(Main.java:35)
at com.google.gson.TreeTypeAdapter.read(TreeTypeAdapter.java:58)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:103)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:196)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:81)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:60)
at com.google.gson.Gson.fromJson(Gson.java:810)
at com.google.gson.Gson.fromJson(Gson.java:775)
at com.google.gson.Gson.fromJson(Gson.java:724)
at com.company.Main.main(Main.java:40)
3条答案
按热度按时间7lrncoxx1#
您需要注册LocalDateTime:例如,替换
Gson gson = new Gson();
,参见以下代码:更新了答案,使用日期格式化程序解析LocalDateTime,而不是创建Instant。此外,您的日期格式不一致,因为一些返回秒,其他返回毫秒,所以我提供了两种格式替代方案。
请参阅使用简化Agent类的示例代码
和Agent类
并且输出
ctrmrzij2#
您可以使用GsonUtils。但请注意以下问题:您在此字段中有一个不同的日期/时间格式。这是不正确的,因为要解析此字段,您必须使用所需的模板设置日期/时间格式化程序。我已经更改了
LastAgentStrategyRun
字段中的格式,下面是一个示例:nfg76nw03#
有时我们必须同时定义串行器和解串器。
范例