diff --git a/java-client/src/main/java/co/elastic/clients/json/JsonpDeserializerBase.java b/java-client/src/main/java/co/elastic/clients/json/JsonpDeserializerBase.java index df16c9e90..4a3fb15cc 100644 --- a/java-client/src/main/java/co/elastic/clients/json/JsonpDeserializerBase.java +++ b/java-client/src/main/java/co/elastic/clients/json/JsonpDeserializerBase.java @@ -312,8 +312,13 @@ public List deserialize(JsonParser parser, JsonpMapper mapper, Event event) { if (event == Event.START_ARRAY) { List result = new ArrayList<>(); while ((event = parser.next()) != Event.END_ARRAY) { - JsonpUtils.ensureAccepts(itemDeserializer, parser, event); - result.add(itemDeserializer.deserialize(parser, mapper, event)); + // JSON null: add null unless the deserializer can handle it + if (event == Event.VALUE_NULL && !itemDeserializer.accepts(event)) { + result.add(null); + } else { + JsonpUtils.ensureAccepts(itemDeserializer, parser, event); + result.add(itemDeserializer.deserialize(parser, mapper, event)); + } } return result; } else { diff --git a/java-client/src/test/java/co/elastic/clients/elasticsearch/model/BuiltinTypesTest.java b/java-client/src/test/java/co/elastic/clients/elasticsearch/model/BuiltinTypesTest.java index 8e39a4165..716d4f776 100644 --- a/java-client/src/test/java/co/elastic/clients/elasticsearch/model/BuiltinTypesTest.java +++ b/java-client/src/test/java/co/elastic/clients/elasticsearch/model/BuiltinTypesTest.java @@ -27,8 +27,11 @@ import co.elastic.clients.elasticsearch._types.query_dsl.SpanGapQuery; import co.elastic.clients.elasticsearch.core.SearchRequest; import co.elastic.clients.elasticsearch.indices.IndexSettings; +import co.elastic.clients.json.JsonpDeserializer; +import jakarta.json.stream.JsonParser; import org.junit.Test; +import java.io.StringReader; import java.util.List; public class BuiltinTypesTest extends ModelTestCase { @@ -50,6 +53,38 @@ public void testLenientArray() { assertGetterType(List.class, SearchRequest.class, "index"); } + @Test + public void testNullArrayItem() { + // See https://github.com/elastic/elasticsearch-java/issues/66 + + String json = "[\"a\", null, \"c\"]"; + + // Types that don't accept null events should end up as null values in the list + { + JsonpDeserializer stringDeser = JsonpDeserializer.stringDeserializer(); + assertFalse(stringDeser.accepts(JsonParser.Event.VALUE_NULL)); + + JsonParser parser = mapper.jsonProvider().createParser(new StringReader(json)); + + List stringList = JsonpDeserializer.arrayDeserializer(stringDeser).deserialize(parser, mapper); + assertEquals("a", stringList.get(0)); + assertNull(stringList.get(1)); + assertEquals("c", stringList.get(2)); + } + + // Types that do accept null events should end up as their null representation + { + assertTrue(FieldValue._DESERIALIZER.accepts(JsonParser.Event.VALUE_NULL)); + + JsonParser parser = mapper.jsonProvider().createParser(new StringReader(json)); + List valueList = JsonpDeserializer.arrayDeserializer(FieldValue._DESERIALIZER).deserialize(parser, mapper); + + assertEquals("a", valueList.get(0)._get()); + assertTrue(valueList.get(1).isNull()); + assertEquals("c", valueList.get(2)._get()); + } + } + @Test public void testSpanGapQuery() { // Hand-written class