Skip to content

Commit

Permalink
Make NettyJsonHandler implement NettyBodyWriter (#10339)
Browse files Browse the repository at this point in the history
This leads to a slight speedup in #10131 but can be merged without the rest of the PR. Not sure if this has impact outside of #10131.
  • Loading branch information
yawkat authored Jan 8, 2024
1 parent 7082803 commit 34bf0ea
Showing 1 changed file with 30 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,38 @@
import io.micronaut.context.annotation.Replaces;
import io.micronaut.context.annotation.Requires;
import io.micronaut.core.annotation.Internal;
import io.micronaut.core.annotation.NonNull;
import io.micronaut.core.io.buffer.ByteBuffer;
import io.micronaut.core.io.buffer.ByteBufferFactory;
import io.micronaut.core.type.Argument;
import io.micronaut.core.type.Headers;
import io.micronaut.core.type.MutableHeaders;
import io.micronaut.http.HttpHeaders;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.MediaType;
import io.micronaut.http.MutableHttpResponse;
import io.micronaut.http.annotation.Consumes;
import io.micronaut.http.annotation.Produces;
import io.micronaut.http.body.ChunkedMessageBodyReader;
import io.micronaut.http.body.MessageBodyHandler;
import io.micronaut.http.body.MessageBodyWriter;
import io.micronaut.http.codec.CodecException;
import io.micronaut.http.netty.NettyHttpHeaders;
import io.micronaut.json.JsonFeatures;
import io.micronaut.json.JsonMapper;
import io.micronaut.json.body.JsonMessageHandler;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufOutputStream;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.EmptyHttpHeaders;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpVersion;
import jakarta.inject.Singleton;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Flux;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

Expand Down Expand Up @@ -73,7 +85,7 @@
})
@BootstrapContextCompatible
@Requires(beans = JsonMapper.class)
public final class NettyJsonHandler<T> implements MessageBodyHandler<T>, ChunkedMessageBodyReader<T>, CustomizableNettyJsonHandler {
public final class NettyJsonHandler<T> implements MessageBodyHandler<T>, ChunkedMessageBodyReader<T>, CustomizableNettyJsonHandler, NettyBodyWriter<T> {
private final JsonMessageHandler<T> jsonMessageHandler;

public NettyJsonHandler(JsonMapper jsonMapper) {
Expand Down Expand Up @@ -137,6 +149,23 @@ public ByteBuffer<?> writeTo(Argument<T> type, MediaType mediaType, T object, Mu
return jsonMessageHandler.writeTo(type, mediaType, object, outgoingHeaders, bufferFactory);
}

@Override
public @NonNull void writeTo(@NonNull HttpRequest<?> request, @NonNull MutableHttpResponse<T> outgoingResponse, @NonNull Argument<T> type, @NonNull MediaType mediaType, @NonNull T object, @NonNull NettyWriteContext nettyContext) throws CodecException {
NettyHttpHeaders nettyHttpHeaders = (NettyHttpHeaders) outgoingResponse.getHeaders();
if (!nettyHttpHeaders.contains(HttpHeaders.CONTENT_TYPE)) {
nettyHttpHeaders.set(HttpHeaderNames.CONTENT_TYPE, mediaType);
}
ByteBuf buffer = nettyContext.alloc().buffer();
JsonMapper jsonMapper = jsonMessageHandler.getJsonMapper();
try {
jsonMapper.writeValue(new ByteBufOutputStream(buffer), object);
} catch (IOException e) {
buffer.release();
throw new CodecException("Error encoding object [" + object + "] to JSON: " + e.getMessage(), e);
}
nettyContext.writeFull(new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.valueOf(outgoingResponse.code(), outgoingResponse.reason()), buffer, nettyHttpHeaders.getNettyHeaders(), EmptyHttpHeaders.INSTANCE));
}

@Override
public MessageBodyWriter<T> createSpecific(Argument<T> type) {
return new NettyJsonHandler<>((JsonMessageHandler<T>) jsonMessageHandler.createSpecific(type));
Expand Down

0 comments on commit 34bf0ea

Please sign in to comment.