From d2ad56e06a56018b1a7efc7f2b5cf9cc9ea2cfe8 Mon Sep 17 00:00:00 2001 From: Denis Stepanov Date: Wed, 15 Nov 2023 14:41:13 +0100 Subject: [PATCH] Integrate `@JsonView` and correct no-view behaviour (#680) --- .../jackson/annotation/JsonViewSpec.groovy | 123 ------------------ .../annotation/SerdeJsonViewSpec.groovy | 6 + .../serde/support/DefaultSerdeRegistry.java | 6 + 3 files changed, 12 insertions(+), 123 deletions(-) delete mode 100644 serde-jackson/src/test/groovy/io/micronaut/serde/jackson/annotation/JsonViewSpec.groovy create mode 100644 serde-jackson/src/test/groovy/io/micronaut/serde/jackson/annotation/SerdeJsonViewSpec.groovy diff --git a/serde-jackson/src/test/groovy/io/micronaut/serde/jackson/annotation/JsonViewSpec.groovy b/serde-jackson/src/test/groovy/io/micronaut/serde/jackson/annotation/JsonViewSpec.groovy deleted file mode 100644 index c53d76359..000000000 --- a/serde-jackson/src/test/groovy/io/micronaut/serde/jackson/annotation/JsonViewSpec.groovy +++ /dev/null @@ -1,123 +0,0 @@ -package io.micronaut.serde.jackson.annotation - -import io.micronaut.serde.jackson.JsonCompileSpec - -class JsonViewSpec extends JsonCompileSpec { - void 'test JsonView with simple properties'() { - given: - def context = buildContext(''' -package jsonviews; - -import com.fasterxml.jackson.annotation.JsonView; -import io.micronaut.core.annotation.Introspected; -import io.micronaut.serde.annotation.Serdeable; -import io.micronaut.serde.jackson.annotation.Views; - -@Serdeable -@Introspected(accessKind = Introspected.AccessKind.FIELD) -class Item { - - @JsonView(Views.Public.class) - public int id; - - @JsonView(Views.Public.class) - public String itemName; - - @JsonView(Views.Internal.class) - public String ownerName; -} - -''') - def item = newInstance(context, 'jsonviews.Item') - item.id = 10 - item.itemName = 'Apple' - item.ownerName = 'Fred' - - when: - def publicMapper = jsonMapper.cloneWithViewClass(Views.Public) - def internalMapper = jsonMapper.cloneWithViewClass(Views.Internal) - def defaultResult = writeJson(publicMapper, item) - def publicResult = writeJson(jsonMapper, item) - def internalResult = writeJson(internalMapper, item) - - then: - publicResult != defaultResult - publicResult != internalResult - defaultResult == '{"id":10,"itemName":"Apple"}' - publicResult == '{}' - internalResult == '{"id":10,"itemName":"Apple","ownerName":"Fred"}' - - when: - def read = publicMapper.readValue(internalResult, argumentOf(context, 'jsonviews.Item')) - - then: - read.id - read.itemName - read.ownerName == null - - cleanup: - context.close() - } - - void 'test JsonView with records'() { - given: - def context = buildContext(''' -package jsonviews; - -import com.fasterxml.jackson.annotation.JsonView; -import io.micronaut.core.annotation.Introspected; -import io.micronaut.core.annotation.Nullable; -import io.micronaut.serde.annotation.Serdeable; -import io.micronaut.serde.jackson.annotation.Views; - -@Serdeable -record Item( - - @JsonView(Views.Public.class) - int id, - - @JsonView(Views.Public.class) - String itemName, - - @JsonView(Views.Internal.class) - @Nullable - String ownerName -) {} - -''') - def item = newInstance(context, 'jsonviews.Item', 10, "Apple", "Fred") - - when: - def publicMapper = jsonMapper.cloneWithViewClass(Views.Public) - def internalMapper = jsonMapper.cloneWithViewClass(Views.Internal) - def defaultResult = writeJson(publicMapper, item) - def publicResult = writeJson(jsonMapper, item) - def internalResult = writeJson(internalMapper, item) - - then: - publicResult != defaultResult - publicResult != internalResult - defaultResult == '{"id":10,"itemName":"Apple"}' - publicResult == '{}' - internalResult == '{"id":10,"itemName":"Apple","ownerName":"Fred"}' - - when: - def read = publicMapper.readValue(internalResult, argumentOf(context, 'jsonviews.Item')) - - then: - read.id - read.itemName - read.ownerName == null - - cleanup: - context.close() - } -} - -class Views { - static class Public { - } - - static class Internal extends Public { - } -} diff --git a/serde-jackson/src/test/groovy/io/micronaut/serde/jackson/annotation/SerdeJsonViewSpec.groovy b/serde-jackson/src/test/groovy/io/micronaut/serde/jackson/annotation/SerdeJsonViewSpec.groovy new file mode 100644 index 000000000..935a53074 --- /dev/null +++ b/serde-jackson/src/test/groovy/io/micronaut/serde/jackson/annotation/SerdeJsonViewSpec.groovy @@ -0,0 +1,6 @@ +package io.micronaut.serde.jackson.annotation + +import io.micronaut.serde.jackson.JsonViewSpec + +class SerdeJsonViewSpec extends JsonViewSpec { +} diff --git a/serde-support/src/main/java/io/micronaut/serde/support/DefaultSerdeRegistry.java b/serde-support/src/main/java/io/micronaut/serde/support/DefaultSerdeRegistry.java index d90d992c0..0a296cfde 100644 --- a/serde-support/src/main/java/io/micronaut/serde/support/DefaultSerdeRegistry.java +++ b/serde-support/src/main/java/io/micronaut/serde/support/DefaultSerdeRegistry.java @@ -453,6 +453,9 @@ public Serializer.EncoderContext newEncoderContext(Class view) { return new DefaultEncoderContext(this) { @Override public boolean hasView(Class... views) { + if (view == null || view == Object.class) { + return true; + } for (Class candidate : views) { if (candidate.isAssignableFrom(view)) { return true; @@ -471,6 +474,9 @@ public Deserializer.DecoderContext newDecoderContext(Class view) { return new DefaultDecoderContext(this) { @Override public boolean hasView(Class... views) { + if (view == null || view == Object.class) { + return true; + } for (Class candidate : views) { if (candidate.isAssignableFrom(view)) { return true;