From 3b3f0f05131191e8536b8bbc1691473707c06c1b Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Thu, 31 Aug 2023 10:38:09 +0300 Subject: [PATCH] Properly support @JsonView on Resource class Fixes: #35639 --- .../ResteasyReactiveJacksonProcessor.java | 2 +- .../deployment/test/JsonViewOnClassTest.java | 81 +++++++++++++++++++ .../deployment/test/SimpleJsonResource.java | 15 +--- .../jackson/deployment/test/User.java | 7 ++ ...ResteasyReactiveServerJacksonRecorder.java | 8 +- ...eaturedServerJacksonMessageBodyReader.java | 7 ++ ...eaturedServerJacksonMessageBodyWriter.java | 7 ++ 7 files changed, 113 insertions(+), 14 deletions(-) create mode 100644 extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/JsonViewOnClassTest.java diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/main/java/io/quarkus/resteasy/reactive/jackson/deployment/processor/ResteasyReactiveJacksonProcessor.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/main/java/io/quarkus/resteasy/reactive/jackson/deployment/processor/ResteasyReactiveJacksonProcessor.java index 564b1ed477e7a..74f4cc444bc45 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/main/java/io/quarkus/resteasy/reactive/jackson/deployment/processor/ResteasyReactiveJacksonProcessor.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/main/java/io/quarkus/resteasy/reactive/jackson/deployment/processor/ResteasyReactiveJacksonProcessor.java @@ -237,7 +237,7 @@ void handleJsonAnnotations(Optional resourceSca if ((jsonViews == null) || (jsonViews.length == 0)) { continue; } - recorder.recordJsonView(getMethodId(instance.target().asMethod()), jsonViews[0].name().toString()); + recorder.recordJsonView(getTargetId(instance.target()), jsonViews[0].name().toString()); } } if (resourceClass.annotationsMap().containsKey(CUSTOM_SERIALIZATION)) { diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/JsonViewOnClassTest.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/JsonViewOnClassTest.java new file mode 100644 index 0000000000000..a57668d4aef4c --- /dev/null +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/JsonViewOnClassTest.java @@ -0,0 +1,81 @@ +package io.quarkus.resteasy.reactive.jackson.deployment.test; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.not; + +import java.util.function.Supplier; + +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; + +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import com.fasterxml.jackson.annotation.JsonView; + +import io.quarkus.test.QuarkusUnitTest; + +class JsonViewOnClassTest { + + @RegisterExtension + static QuarkusUnitTest test = new QuarkusUnitTest() + .setArchiveProducer(new Supplier<>() { + @Override + public JavaArchive get() { + return ShrinkWrap.create(JavaArchive.class) + .addClasses(User.class, Views.class, Public.class, Private.class, Mixed.class); + } + }); + + @Test + void test() { + given().accept("application/json").get("public") + .then() + .statusCode(200) + .body(not(containsString("1")), containsString("test")); + + given().accept("application/json").get("mixed") + .then() + .statusCode(200) + .body(containsString("1"), containsString("test")); + + given().accept("application/json").get("private") + .then() + .statusCode(200) + .body(containsString("1"), containsString("test")); + } + + @JsonView(Views.Public.class) + @Path("public") + public static class Public { + + @GET + public User get() { + return User.testUser(); + } + } + + @JsonView(Views.Private.class) + @Path("private") + public static class Private { + + @GET + public User get() { + return User.testUser(); + } + } + + @JsonView(Views.Public.class) + @Path("mixed") + public static class Mixed { + + @GET + @JsonView(Views.Private.class) + public User get() { + return User.testUser(); + } + } +} diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/SimpleJsonResource.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/SimpleJsonResource.java index 8e5f215debb6b..b538997b62f25 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/SimpleJsonResource.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/SimpleJsonResource.java @@ -255,35 +255,28 @@ public void run() { @GET @Path("/user-without-view") public User userWithoutView() { - return testUser(); + return User.testUser(); } @JsonView(Views.Public.class) @GET @Path("/user-with-public-view") public User userWithPublicView() { - return testUser(); + return User.testUser(); } @JsonView(Views.Private.class) @GET @Path("/user-with-private-view") public User userWithPrivateView() { - return testUser(); + return User.testUser(); } @CustomSerialization(UnquotedFieldsPersonSerialization.class) @GET @Path("/invalid-use-of-custom-serializer") public User invalidUseOfCustomSerializer() { - return testUser(); - } - - private User testUser() { - User user = new User(); - user.id = 1; - user.name = "test"; - return user; + return User.testUser(); } @GET diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/User.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/User.java index 795da2ebfd2b4..f588592f23b3c 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/User.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/User.java @@ -9,4 +9,11 @@ public class User { @JsonView(Views.Public.class) public String name; + + public static User testUser() { + User user = new User(); + user.id = 1; + user.name = "test"; + return user; + } } diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/ResteasyReactiveServerJacksonRecorder.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/ResteasyReactiveServerJacksonRecorder.java index eed5cd09521f6..2e86508b9f498 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/ResteasyReactiveServerJacksonRecorder.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/ResteasyReactiveServerJacksonRecorder.java @@ -19,8 +19,8 @@ public class ResteasyReactiveServerJacksonRecorder { private static final Map> customSerializationMap = new HashMap<>(); private static final Map> customDeserializationMap = new HashMap<>(); - public void recordJsonView(String methodId, String className) { - jsonViewMap.put(methodId, loadClass(className)); + public void recordJsonView(String targetId, String className) { + jsonViewMap.put(targetId, loadClass(className)); } public void recordCustomSerialization(String target, String className) { @@ -42,6 +42,10 @@ public void run() { }); } + public static Class jsonViewForClass(Class clazz) { + return jsonViewMap.get(clazz.getName()); + } + public static Class jsonViewForMethod(String methodId) { return jsonViewMap.get(methodId); } diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/serialisers/FullyFeaturedServerJacksonMessageBodyReader.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/serialisers/FullyFeaturedServerJacksonMessageBodyReader.java index dab95f4f402be..89dbe47c6d36a 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/serialisers/FullyFeaturedServerJacksonMessageBodyReader.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/serialisers/FullyFeaturedServerJacksonMessageBodyReader.java @@ -175,6 +175,13 @@ public ObjectReader apply(ObjectMapper objectMapper) { Class jsonViewValue = ResteasyReactiveServerJacksonRecorder.jsonViewForMethod(resourceInfo.getMethodId()); if (jsonViewValue != null) { return effectiveReader.withView(jsonViewValue); + } else { + jsonViewValue = ResteasyReactiveServerJacksonRecorder + .jsonViewForClass(resourceInfo.getResourceClass()); + if (jsonViewValue != null) { + return effectiveReader.withView(jsonViewValue); + } + } } } diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/serialisers/FullyFeaturedServerJacksonMessageBodyWriter.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/serialisers/FullyFeaturedServerJacksonMessageBodyWriter.java index abe3896f9a33d..171b6843fa62d 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/serialisers/FullyFeaturedServerJacksonMessageBodyWriter.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/serialisers/FullyFeaturedServerJacksonMessageBodyWriter.java @@ -66,6 +66,13 @@ public void writeResponse(Object o, Type genericType, ServerRequestContext conte Class jsonViewValue = ResteasyReactiveServerJacksonRecorder.jsonViewForMethod(resourceInfo.getMethodId()); if (jsonViewValue != null) { effectiveWriter = effectiveWriter.withView(jsonViewValue); + } else { + jsonViewValue = ResteasyReactiveServerJacksonRecorder + .jsonViewForClass(resourceInfo.getResourceClass()); + if (jsonViewValue != null) { + effectiveWriter = effectiveWriter.withView(jsonViewValue); + } + } } effectiveWriter.writeValue(stream, o);