用于 DateTime 的 Gson 自定义解串器

问题描述

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

无论我尝试什么,我都不断收到上述错误,我什至不知道要调查什么——任何想法都值得赞赏,我不知道还可以尝试什么。

解决方法

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

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...