I have a JestClient (elasticsearch) response that I'm trying to deserialize into an object. The object contains two DateTime fields, whereas in the response, they're strings, so I'm getting:
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:?]
So, I have created a custom deserializer to solve this.. However, whatever I do, I keep getting the same error. Somehow it's not registering to use it?
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);
}
}
I'm also setting my typeAdapter when initializing my client:
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();
}
And finally, the code where I'm trying to parse the response from 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());
No matter what I try I keep getting the error above, I'm not even sure at this point what to investigate-- any ideas are appreciated, I'm not sure what else to try.
This implementation ended up being correct. The reason it wasn't working in my tests was because I needed to add the adapter to the Gson I was initializing:
private static final Gson GSON = new GsonBuilder().registerTypeAdapter(ZonedDateTime.class, new DateTimeConverter()).create();