diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/serialisers/JacksonMessageBodyWriter.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/serialisers/JacksonMessageBodyWriter.java index cb07daea01df0..566e5755e3831 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/serialisers/JacksonMessageBodyWriter.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jackson/runtime/src/main/java/io/quarkus/resteasy/reactive/jackson/runtime/serialisers/JacksonMessageBodyWriter.java @@ -1,6 +1,6 @@ package io.quarkus.resteasy.reactive.jackson.runtime.serialisers; -import static org.jboss.resteasy.reactive.server.vertx.providers.serialisers.json.JsonMessageBodyWriterUtil.*; +import static org.jboss.resteasy.reactive.server.vertx.providers.serialisers.json.JsonMessageBodyWriterUtil.setContentTypeIfNecessary; import java.io.IOException; import java.io.OutputStream; @@ -30,7 +30,7 @@ import io.quarkus.resteasy.reactive.jackson.CustomSerialization; -public class JacksonMessageBodyWriter implements ServerMessageBodyWriter { +public class JacksonMessageBodyWriter extends ServerMessageBodyWriter.AllWriteableMessageBodyWriter { private static final String JSON_VIEW_NAME = JsonView.class.getName(); private static final String CUSTOM_SERIALIZATION = CustomSerialization.class.getName(); @@ -62,11 +62,6 @@ private static void setNecessaryJsonFactoryConfig(JsonFactory jsonFactory) { jsonFactory.configure(Feature.FLUSH_PASSED_TO_STREAM, false); } - @Override - public boolean isWriteable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) { - return true; - } - @Override public void writeTo(Object o, Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException { @@ -87,11 +82,6 @@ public void writeTo(Object o, Class type, Type genericType, Annotation[] anno } } - @Override - public boolean isWriteable(Class type, Type genericType, ResteasyReactiveResourceInfo target, MediaType mediaType) { - return true; - } - @Override public void writeResponse(Object o, Type genericType, ServerRequestContext context) throws WebApplicationException, IOException { diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jsonb/runtime/src/main/java/io/quarkus/resteasy/reactive/jsonb/runtime/serialisers/JsonbMessageBodyWriter.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jsonb/runtime/src/main/java/io/quarkus/resteasy/reactive/jsonb/runtime/serialisers/JsonbMessageBodyWriter.java index f3378c243b688..93bbbf7aaf8bb 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive-jsonb/runtime/src/main/java/io/quarkus/resteasy/reactive/jsonb/runtime/serialisers/JsonbMessageBodyWriter.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-jsonb/runtime/src/main/java/io/quarkus/resteasy/reactive/jsonb/runtime/serialisers/JsonbMessageBodyWriter.java @@ -13,11 +13,10 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; -import org.jboss.resteasy.reactive.server.spi.ResteasyReactiveResourceInfo; import org.jboss.resteasy.reactive.server.spi.ServerMessageBodyWriter; import org.jboss.resteasy.reactive.server.spi.ServerRequestContext; -public class JsonbMessageBodyWriter implements ServerMessageBodyWriter { +public class JsonbMessageBodyWriter extends ServerMessageBodyWriter.AllWriteableMessageBodyWriter { private final Jsonb json; @@ -26,11 +25,6 @@ public JsonbMessageBodyWriter(Jsonb json) { this.json = json; } - @Override - public boolean isWriteable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) { - return true; - } - @Override public void writeTo(Object o, Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException { @@ -42,11 +36,6 @@ public void writeTo(Object o, Class type, Type genericType, Annotation[] anno } } - @Override - public boolean isWriteable(Class type, Type genericType, ResteasyReactiveResourceInfo target, MediaType mediaType) { - return true; - } - @Override public void writeResponse(Object o, Type genericType, ServerRequestContext context) throws WebApplicationException, IOException { diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/startup/RuntimeResourceDeployment.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/startup/RuntimeResourceDeployment.java index 9eea8378dbf83..619402e365038 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/startup/RuntimeResourceDeployment.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/startup/RuntimeResourceDeployment.java @@ -294,9 +294,7 @@ public RuntimeResource buildResourceMethod(ResourceClass clazz, + "#" + method.getName() + "(" + Arrays.toString(method.getParameters()) + ")"); handlers.add(new VariableProducesHandler(serverMediaType, serialisers)); score.add(ScoreSystem.Category.Writer, ScoreSystem.Diagnostic.WriterRunTime); - } else if (buildTimeWriters.size() == 1) { - //only a single handler that can handle the response - //this is a very common case + } else if (isSingleEffectiveWriter(buildTimeWriters)) { MessageBodyWriter writer = buildTimeWriters.get(0); handlers.add(new FixedProducesHandler(mediaType, new FixedEntityWriter( writer, serialisers))); @@ -366,6 +364,16 @@ public RuntimeResource buildResourceMethod(ResourceClass clazz, return runtimeResource; } + private boolean isSingleEffectiveWriter(List> buildTimeWriters) { + if (buildTimeWriters.size() == 1) { // common case of single writer + return true; + } + + // in the case where the first Writer is an instance of AllWriteableMessageBodyWriter, + // it doesn't matter that we have multiple writers as the first one will always be used to serialize + return buildTimeWriters.get(0) instanceof ServerMessageBodyWriter.AllWriteableMessageBodyWriter; + } + private void addHandlers(List handlers, ServerResourceMethod method, DeploymentInfo info, HandlerChainCustomizer.Phase phase) { for (HandlerChainCustomizer i : info.getGlobalHandlerCustomers()) { diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/spi/ServerMessageBodyWriter.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/spi/ServerMessageBodyWriter.java index 92d14da3c4f61..7c794519b6b53 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/spi/ServerMessageBodyWriter.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/spi/ServerMessageBodyWriter.java @@ -1,6 +1,7 @@ package org.jboss.resteasy.reactive.server.spi; import java.io.IOException; +import java.lang.annotation.Annotation; import java.lang.reflect.Type; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MediaType; @@ -15,4 +16,24 @@ public interface ServerMessageBodyWriter extends MessageBodyWriter { void writeResponse(T o, Type genericType, ServerRequestContext context) throws WebApplicationException, IOException; + /** + * A special super-class of MessageBodyWriters that accepts all types of input. + * The main purpose of this class is to allow runtime code + * to optimize for the case when there are multiple providers determined at build time + * but the first one will always be used + */ + abstract class AllWriteableMessageBodyWriter implements ServerMessageBodyWriter { + + @Override + public final boolean isWriteable(Class type, Type genericType, ResteasyReactiveResourceInfo target, + MediaType mediaType) { + return true; + } + + @Override + public final boolean isWriteable(Class type, Type genericType, + Annotation[] annotations, MediaType mediaType) { + return true; + } + } }