DateTime的Gson自订还原序列化程式

6ss1mwsb  于 2022-11-06  发布在  其他
关注(0)|答案(1)|浏览(177)

我有一个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);
    }
}

我还在初始化客户端时设置了typeAdapter:

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());

不管我怎么尝试,我总是得到上面的错误,我甚至不知道在这一点上要调查什么-任何想法都是赞赏,我不知道还有什么要尝试。

iq3niunx

iq3niunx1#

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

private static final Gson GSON = new GsonBuilder().registerTypeAdapter(ZonedDateTime.class, new DateTimeConverter()).create();

相关问题