FasterXML / jackson-databind

General data-binding package for Jackson (2.x): works on streaming API (core) implementation(s)
Apache License 2.0
3.52k stars 1.38k forks source link

setSerializationInclusion(JsonInclude.Include.NON_EMPTY doesn't filter empty values from collections #4640

Open Gems opened 2 months ago

Gems commented 2 months ago

Search before asking

Describe the bug

Empty Map values in collections don't get filtered out.

Version Information

2.17.2

Reproduction

Here is code for the corresponding unit test:

    final var objectMapper = new ObjectMapper()
        .setSerializationInclusion(JsonInclude.Include.NON_EMPTY);

    final var payload = Map.of(
        "key", "value",
        "empty", Map.of(),
        "list", List.of(
            Map.of("key", "value"),
            Map.of(),
            Map.of(),
            Map.of("key", "value")));

    final var json = objectMapper.writeValueAsString(payload);
    final var deserialized = (Map<?,?>) objectMapper.readValue(json, Map.class);

    final var expected = Map.of(
        "key", "value",
        "list", List.of(
            Map.of("key", "value"),
            Map.of("key", "value")));

    assertThat(deserialized)
        .isEqualTo(expected);

Expected behavior

It's expected that the test would pass.

Additional context

No response

yawkat commented 2 months ago

I believe JsonInclude only applies to beans and maps.

cowtowncoder commented 2 months ago

Kind of: It does apply to Collections wrt "simple" empty case, but it does not filter elements. So only ones with Collection.isEmpty() are filtered out, but not ones where there are elements that would be considered empty.

Gems commented 2 months ago

Yeah, I noticed it. But I don't think that it's expected behavior that comes to ones mind when then learn about the "non_empty" option.

I pathed the SerializerFactory to make it to produce a CollectionSerializer implented the same way the MapSerializer is implemented. Works well.

I believe it could be a more straightforward behavior having empty collection/array items filtered out in case of the "non_empty" option is provided.

cowtowncoder commented 2 months ago

Changing this behavior would be major backwards-compatibility problem tho. And conceptually skipping is only for properties (of POJOs, Maps), not for elements (of Collections, arrays).

So while I understand why it's confusing, I don't think this is something I want to change.

Gems commented 2 months ago

No problem. I have my workaround implemented and it solves the problem we have.

Feel free to close the issue.

I'd suggest though leaving it open for comments, so I can share a relevant solution if anyone else has the same issue.

Cheers, Ed

cowtowncoder commented 2 months ago

Will leave open for bit, close in future -- closed issued should be googlable still.