当前位置: 首页 > 知识库问答 >
问题:

Gson自定义DateTime反序列化器

笪健
2023-03-14

我有一个JestClient(elasticsearch)响应,我试图将其反序列化为一个对象。该对象包含两个DateTime字段,而在响应中,它们是字符串,因此我得到:

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 102 path $.createdTimeStamp
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:226) ~[gson-2.8.5.jar:?]
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:131) ~[gson-2.8.5.jar:?]
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:222) ~[gson-2.8.5.jar:?]
    at com.google.gson.Gson.fromJson(Gson.java:927) ~[gson-2.8.5.jar:?]
    at com.google.gson.Gson.fromJson(Gson.java:892) ~[gson-2.8.5.jar:?]
    at com.google.gson.Gson.fromJson(Gson.java:841) ~[gson-2.8.5.jar:?]
    at com.google.gson.Gson.fromJson(Gson.java:813) ~[gson-2.8.5.jar:?]
    at io.searchbox.client.JestResult.createSourceObject(JestResult.java:271) ~[Jest-6.x.jar:?]
    at io.searchbox.core.SearchResult.access$000(SearchResult.java:17) ~[Jest-6.x.jar:?]
    at io.searchbox.core.SearchResult$Hit.<init>(SearchResult.java:288) ~[Jest-6.x.jar:?]
    at io.searchbox.core.SearchResult.extractHit(SearchResult.java:163) ~[Jest-6.x.jar:?]
    at io.searchbox.core.SearchResult.getHits(SearchResult.java:92) ~[Jest-6.x.jar:?]
    at io.searchbox.core.SearchResult.getHits(SearchResult.java:73) ~[Jest-6.x.jar:?]
    at io.searchbox.core.SearchResult.getHits(SearchResult.java:65) ~[Jest-6.x.jar:?]
    at io.searchbox.core.SearchResult.getHits(SearchResult.java:61) ~[Jest-6.x.jar:?]

所以,我创建了一个自定义反序列化器来解决这个问题…然而,无论我做什么,我总是得到同样的错误。不知何故它没有注册使用它?

public final class DateTimeConverter extends TypeAdapter<DateTime> {

    @Override
    public void write(JsonWriter jsonWriter, DateTime dateTime) throws IOException {
        if (Objects.isNull(dateTime)) {
            jsonWriter.nullValue();
            return;
        }
        jsonWriter.value(dateTime.toString());
    }

    @Override
    public DateTime read(JsonReader jsonReader) throws IOException {
        System.out.println("This statement doesn't print, so I'm assuming this method isn't being used during parsing");
        String dateTimeString = jsonReader.nextString();
        return DateTime.parse(dateTimeString);
    }
}
    public JestClient getElasticsearchJestClient(@NonNull final AWSCredentialsProvider awsCredentialsProvider, @NonNull final Regions region) {
        Gson gson = new GsonBuilder().registerTypeAdapter(DateTime.class, new DateTimeConverter()).create();
        AESClientFactory factory = new AESClientFactory(awsCredentialsProvider, region.getName());
        factory.setHttpClientConfig(new HttpClientConfig.Builder(ENDPOINT)
                .multiThreaded(true)
                .gson(gson).build());
        return factory.getObject();
    }

最后,我试图解析JestClient响应的代码:

  List<SearchResult.Hit<MyObject, Void>> hits;
  SearchResult result = elasticsearchAccessor.getElasticsearchRecords(search);
  hits = result.getHits(MyObject.class);
  final List<MyObject> objects = hits.stream()
       .map((hit) -> hit.source)
       .collect(Collectors.toList());

无论我尝试什么,我总是得到上面的错误,我甚至不确定在这一点上调查什么--任何想法都被欣赏,我不确定还有什么可以尝试。

共有1个答案

璩浩广
2023-03-14

这个实现最终是正确的。它在我的测试中不起作用的原因是因为我需要将适配器添加到我正在初始化的Gson中:

    private static final Gson GSON = new GsonBuilder().registerTypeAdapter(ZonedDateTime.class, new DateTimeConverter()).create();
 类似资料:
  • 问题内容: 确定,所以我编辑了问题,因为它不够清楚。 编辑2 :更新了JSON文件。 我在Android应用程序中使用GSON,我需要解析来自服务器的JSON文件,这些文件有点太复杂了。我不想让我的对象结构太沉重,所以我想简化内容: 所以我的对象的结构将不是JSON文件的结构。 例如,如果在JSON中,我有以下内容: 我不想保留我当前的对象结构,即一个对象,其中包含一个和一个“总计”。但是我只想将

  • 问题内容: 我在使用Gson解析JSON响应时遇到问题。 JSON字串: 我有这两个课程: 但是当使用Gson解析这个时我有一个异常。我知道这是因为响应数组的第一个元素不是对象,而是整数。 所以问题是,我能以某种方式解决它吗? 问题答案: 您必须编写一个 自定义反序列化器 。我会做这样的事情: 首先,您需要包括一个新的类,而不是已有的两个类: 然后,您需要一个自定义解串器,类似于以下内容: 然后,

  • 问题内容: 我需要反序列化json,它是日期/长值的数组。这是返回的JSON的示例: 使用GSON,我可以将其反序列化为,但希望能够将其转换为类似以下内容的方法: 我似乎找不到一种方法来指示GSON将JSON映射的键/值映射到我的自定义类中的日期/值字段。有没有办法做到这一点,还是地图列表是唯一的路线? 问题答案: 您需要编写一个自定义解串器。您还需要使用可以实际解析的时区格式。无论是也将匹配,这

  • 据我所知,gson不会自动将java.util.Date对象序列化和反序列化为ISO字符串,比如“yyyy-mm-ddthh:mm:ssz”或“2014-04-15t18:22:00-05:00”。因此,为了让我在客户机(使用gson改型)和服务器之间正确地通信日期,我需要指定gson的日期格式。以下是我所做的: 添加。SetDateFormat行就足以让gson正确地将时间戳字符串反序列化为日期

  • 我想反序列化表单中的类: 其中文本是加密的,反序列化应该在重建TestFieldEncryptedMessage实例之前取消对值的加密。 我采用的方法非常类似于:https://github.com/codesqueak/jackson-json-crypto 也就是说,我正在构建一个扩展SimpleModule的模块: 如您所见,设置了两个修饰符:EncryptedSerializerModif

  • 我有一个不能用Gson正确序列化的类(类只是name和HashMap),所以我编写了一个自定义序列化程序来从HashMap中打印名称和键值对。 此外,这是实际打印的内容,序列化整个对象并不像我所期望的那样工作,也不只是直接打印对象。 任何帮助都将不胜感激。