OpenSearch Java client seamlessly integrates with JSON, providing serialization and deserialization capability.
For demonstration let's consider an instance of SearchRequest
.
SearchRequest searchRequest = SearchRequest.of(
request -> request.index("index1", "index2")
.aggregations(Collections.emptyMap())
.terminateAfter(5L)
.query(q -> q.match(t -> t.field("name").query(FieldValue.of("OpenSearch"))))
);
For classes implementing PlainJsonSerializable
, which extends JsonpSerializable
, a default toJsonString
method is provided.
This implementation uses jakarta.json.spi.JsonProvider
SPI to discover the available JSON provider instance
from the classpath and to create a new mapper. The JsonpUtils
utility class streamlines this serialization process.
The following code example demonstrates how to use the toJsonString
method to serialize objects:
String requestString = searchRequest.toJsonString();
For classes implementing the JsonpSerializable
interface, a serialize method is provided, which takes a mapper and a generator
as arguments and returns the JSON string representation of the instance.
The following sample code demonstrates how to serialize an instance of a Java class:
private String toJson(JsonpSerializable object) {
try (StringWriter writer = new StringWriter()) {
JsonbJsonpMapper mapper = new JsonbJsonpMapper();
try (JsonGenerator generator = mapper.jsonProvider().createGenerator(writer)) {
serialize(generator, mapper);
}
return writer.toString();
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}
By default, the JSON serialization of the OpenSearch Java client uses typed keys for certain types, notably Aggregations.
This is done for the benefit of unambiguous deserialization, but may result in JSON output that is incompatible with use-cases expecting OpenSearch's default untyped keys.
You may disable this behavior by setting the JsonpMapperAttributes.SERIALIZE_TYPED_KEYS
attribute to false
on a JsonpMapper instance.
For example, the following code demonstrates how to serialize a SearchResponse without typed keys:
private String withoutTypedKeys(OpenSearchClient client, SearchResponse response) {
JsonpMapper mapper = client._transport().jsonpMapper().withAttribute(JsonpMapperAttributes.SERIALIZE_TYPED_KEYS, false);
StringWriter writer = new StringWriter();
try (JsonGenerator generator = mapper.jsonProvider().createGenerator(writer)) {
response.serialize(generator, mapper);
}
return writer.toString();
}
For demonstration let's consider an IndexTemplateMapping JSON String.
String stringTemplate =
"{\"mappings\":{\"properties\":{\"age\":{\"type\":\"integer\"}}},\"settings\":{\"number_of_shards\":\"2\",\"number_of_replicas\":\"1\"}}";
For classes, Builders of which implements PlainDeserializable
interface, a default withJson
method is provided.
The withJson method returns the Builder enabling you to chain Builder methods for additional configuration.
This implementation uses jakarta.json.spi.JsonProvider
SPI to discover the available JSON provider instance
from the classpath and to create a new mapper. The JsonpUtils
utility class streamlines this deserialization process.
The following code example demonstrates how to use the withJson
method to deserialize objects:
InputStream inputStream = new ByteArrayInputStream(stringTemplate.getBytes(StandardCharsets.UTF_8));
IndexTemplateMapping indexTemplateMapping = new IndexTemplateMapping.Builder().withJson(inputStream).build();
For classes annotated with @JsonpDeserializable
, a static field _DESERIALIZER is provided,
which takes a mapper and a parser as arguments and returns the instance of the json value passed in the parser.
Notice that this way you cannot further customize the instance, the state of which will solely depend on the json value parsed.
The following sample code demonstrates how to serialize an instance of a Java class:
private IndexTemplateMapping getInstance(String templateJsonString) {
InputStream inputStream = new ByteArrayInputStream(templateJsonString.getBytes(StandardCharsets.UTF_8));
JsonbJsonpMapper mapper = new JsonbJsonpMapper();
try (JsonParser parser = mapper.jsonProvider().createParser(inputStream)) {
IndexTemplateMapping indexTemplateMapping = new IndexTemplateMapping._DESERIALIZER.deserialize(parser, mapper);
return indexTemplateMapping;
}
}