use of io.micronaut.web.router.RouteInfo in project micronaut-core by micronaut-projects.
the class RoutingInBoundHandler method mapToHttpContent.
private Flux<HttpContent> mapToHttpContent(NettyHttpRequest<?> request, MutableHttpResponse<?> response, Object body, ChannelHandlerContext context) {
final RouteInfo<?> routeInfo = response.getAttribute(HttpAttributes.ROUTE_INFO, RouteInfo.class).orElse(null);
final boolean hasRouteInfo = routeInfo != null;
MediaType mediaType = response.getContentType().orElse(null);
if (mediaType == null && hasRouteInfo) {
mediaType = routeExecutor.resolveDefaultResponseContentType(request, routeInfo);
}
boolean isJson = mediaType != null && mediaType.getExtension().equals(MediaType.EXTENSION_JSON) && isJsonFormattable(hasRouteInfo ? routeInfo.getBodyType() : null);
NettyByteBufferFactory byteBufferFactory = new NettyByteBufferFactory(context.alloc());
Flux<Object> bodyPublisher = Flux.from(Publishers.convertPublisher(body, Publisher.class));
MediaType finalMediaType = mediaType;
Flux<HttpContent> httpContentPublisher = bodyPublisher.map(message -> {
HttpContent httpContent;
if (message instanceof ByteBuf) {
httpContent = new DefaultHttpContent((ByteBuf) message);
} else if (message instanceof ByteBuffer) {
ByteBuffer<?> byteBuffer = (ByteBuffer<?>) message;
Object nativeBuffer = byteBuffer.asNativeBuffer();
if (nativeBuffer instanceof ByteBuf) {
httpContent = new DefaultHttpContent((ByteBuf) nativeBuffer);
} else {
httpContent = new DefaultHttpContent(Unpooled.copiedBuffer(byteBuffer.asNioBuffer()));
}
} else if (message instanceof byte[]) {
httpContent = new DefaultHttpContent(Unpooled.copiedBuffer((byte[]) message));
} else if (message instanceof HttpContent) {
httpContent = (HttpContent) message;
} else {
MediaTypeCodec codec = mediaTypeCodecRegistry.findCodec(finalMediaType, message.getClass()).orElse(new TextPlainCodec(serverConfiguration.getDefaultCharset()));
if (LOG.isTraceEnabled()) {
LOG.trace("Encoding emitted response object [{}] using codec: {}", message, codec);
}
ByteBuffer<ByteBuf> encoded;
if (hasRouteInfo) {
// noinspection unchecked
final Argument<Object> bodyType = (Argument<Object>) routeInfo.getBodyType();
if (bodyType.isInstance(message)) {
encoded = codec.encode(bodyType, message, byteBufferFactory);
} else {
encoded = codec.encode(message, byteBufferFactory);
}
} else {
encoded = codec.encode(message, byteBufferFactory);
}
httpContent = new DefaultHttpContent(encoded.asNativeBuffer());
}
return httpContent;
});
if (isJson) {
// if the Publisher is returning JSON then in order for it to be valid JSON for each emitted element
// we must wrap the JSON in array and delimit the emitted items
httpContentPublisher = JsonSubscriber.lift(httpContentPublisher);
}
httpContentPublisher = httpContentPublisher.contextWrite(reactorContext -> reactorContext.put(ServerRequestContext.KEY, request)).doOnNext(httpContent -> context.read()).doAfterTerminate(() -> cleanupRequest(context, request));
return httpContentPublisher;
}
use of io.micronaut.web.router.RouteInfo in project micronaut-core by micronaut-projects.
the class RoutingInBoundHandler method encodeResponseBody.
private void encodeResponseBody(ChannelHandlerContext context, HttpRequest<?> request, MutableHttpResponse<?> message, @Nullable Argument<Object> bodyType, Object body) {
if (body == null) {
return;
}
Optional<NettyCustomizableResponseTypeHandler> typeHandler = customizableResponseTypeHandlerRegistry.findTypeHandler(body.getClass());
if (typeHandler.isPresent()) {
NettyCustomizableResponseTypeHandler th = typeHandler.get();
setBodyContent(message, new NettyCustomizableResponseTypeHandlerInvoker(th, body));
} else {
MediaType mediaType = message.getContentType().orElse(null);
if (mediaType == null) {
mediaType = message.getAttribute(HttpAttributes.ROUTE_INFO, RouteInfo.class).map(routeInfo -> routeExecutor.resolveDefaultResponseContentType(request, routeInfo)).orElse(MediaType.APPLICATION_JSON_TYPE);
message.contentType(mediaType);
}
if (body instanceof CharSequence) {
ByteBuf byteBuf = Unpooled.wrappedBuffer(body.toString().getBytes(message.getCharacterEncoding()));
setResponseBody(message, byteBuf);
} else if (body instanceof byte[]) {
ByteBuf byteBuf = Unpooled.wrappedBuffer((byte[]) body);
setResponseBody(message, byteBuf);
} else if (body instanceof ByteBuffer) {
ByteBuffer<?> byteBuffer = (ByteBuffer) body;
Object nativeBuffer = byteBuffer.asNativeBuffer();
if (nativeBuffer instanceof ByteBuf) {
setResponseBody(message, (ByteBuf) nativeBuffer);
} else if (nativeBuffer instanceof java.nio.ByteBuffer) {
ByteBuf byteBuf = Unpooled.wrappedBuffer((java.nio.ByteBuffer) nativeBuffer);
setResponseBody(message, byteBuf);
}
} else if (body instanceof ByteBuf) {
setResponseBody(message, (ByteBuf) body);
} else {
Optional<MediaTypeCodec> registeredCodec = mediaTypeCodecRegistry.findCodec(mediaType, body.getClass());
if (registeredCodec.isPresent()) {
MediaTypeCodec codec = registeredCodec.get();
encodeBodyWithCodec(message, bodyType, body, codec, context, request);
} else {
MediaTypeCodec defaultCodec = new TextPlainCodec(serverConfiguration.getDefaultCharset());
encodeBodyWithCodec(message, bodyType, body, defaultCodec, context, request);
}
}
}
}
Aggregations