/** * Makes sure the specified {@link MediaType} or its compatible one is registered already. */ private static void checkMediaType(Multimap<MediaType, SerializationFormat> simplifiedMediaTypeToFormats, MediaType mediaType) { final MediaType simplifiedMediaType = mediaType.withoutParameters(); for (SerializationFormat format : simplifiedMediaTypeToFormats.get(simplifiedMediaType)) { for (MediaType registeredMediaType : format.mediaTypes()) { checkState(!registeredMediaType.is(mediaType) && !mediaType.is(registeredMediaType), "media type registered already: ", mediaType); } } }
/** * Converts the specified {@link AggregatedHttpMessage} to an object of {@code expectedResultType}. */ @Override @Nullable public Object convertRequest(ServiceRequestContext ctx, AggregatedHttpMessage request, Class<?> expectedResultType) throws Exception { final MediaType contentType = request.headers().contentType(); if (contentType != null && (contentType.is(MediaType.JSON) || contentType.subtype().endsWith("+json"))) { final ObjectReader reader = readers.computeIfAbsent(expectedResultType, mapper::readerFor); if (reader != null) { final String content = request.content().toString( contentType.charset().orElse(StandardCharsets.UTF_8)); try { return reader.readValue(content); } catch (JsonProcessingException e) { throw new IllegalArgumentException("failed to parse a JSON document: " + e, e); } } } return RequestConverterFunction.fallthrough(); } }
@Nullable @Override public Object convertRequest(ServiceRequestContext ctx, AggregatedHttpMessage request, Class<?> expectedResultType) throws Exception { final MediaType mediaType = request.headers().contentType(); if (mediaType != null && mediaType.is(MediaType.PLAIN_TEXT_UTF_8)) { return new Request(request.content().toStringUtf8()); } return RequestConverterFunction.fallthrough(); } }
/** * Converts the specified {@link AggregatedHttpMessage} to an object of {@code expectedResultType}. * This converter allows only {@code byte[]} and {@link HttpData} as its return type, and * {@link AggregatedHttpMessage} would be consumed only if it does not have a {@code Content-Type} header * or if it has {@code Content-Type: application/octet-stream} or {@code Content-Type: application/binary}. */ @Override public Object convertRequest(ServiceRequestContext ctx, AggregatedHttpMessage request, Class<?> expectedResultType) throws Exception { final MediaType mediaType = request.headers().contentType(); if (mediaType == null || mediaType.is(MediaType.OCTET_STREAM) || mediaType.is(MediaType.APPLICATION_BINARY)) { if (expectedResultType == byte[].class) { return request.content().array(); } if (expectedResultType == HttpData.class) { return request.content(); } } return RequestConverterFunction.fallthrough(); } }
/** * Converts the specified {@link AggregatedHttpMessage} to a {@link String}. */ @Override public Object convertRequest(ServiceRequestContext ctx, AggregatedHttpMessage request, Class<?> expectedResultType) throws Exception { if (expectedResultType == String.class || expectedResultType == CharSequence.class) { final MediaType contentType = request.headers().contentType(); if (contentType != null && contentType.is(MediaType.ANY_TEXT_TYPE)) { // See https://tools.ietf.org/html/rfc2616#section-3.7.1 return request.content().toString( contentType.charset().orElse(StandardCharsets.ISO_8859_1)); } } return RequestConverterFunction.fallthrough(); } }
final HttpHeaders unframedHeaders = HttpHeaders.copyOf(grpcResponse.headers()); if (grpcMediaType != null) { if (grpcMediaType.is(GrpcSerializationFormats.PROTO.mediaType())) { unframedHeaders.contentType(MediaType.PROTOBUF); } else if (grpcMediaType.is(GrpcSerializationFormats.JSON.mediaType())) { unframedHeaders.contentType(MediaType.JSON_UTF_8);
@Override public HttpResponse convertResponse(ServiceRequestContext ctx, HttpHeaders headers, @Nullable Object result, HttpHeaders trailingHeaders) throws Exception { final MediaType mediaType = headers.contentType(); if (mediaType != null) { // @Produces("text/plain") or @ProducesText is specified. if (mediaType.is(MediaType.ANY_TEXT_TYPE)) { // Use 'utf-8' charset by default. final Charset charset = mediaType.charset().orElse(StandardCharsets.UTF_8); // To avoid sending an unfinished text to the client, always aggregate the published strings. if (result instanceof Publisher) { return aggregateFrom((Publisher<?>) result, headers, trailingHeaders, o -> toHttpData(o, charset)); } if (result instanceof Stream) { return aggregateFrom((Stream<?>) result, headers, trailingHeaders, o -> toHttpData(o, charset), ctx.blockingTaskExecutor()); } return HttpResponse.of(headers, toHttpData(result, charset), trailingHeaders); } } else if (result instanceof CharSequence) { return HttpResponse.of(toMutableHeaders(headers).contentType(MediaType.PLAIN_TEXT_UTF_8), HttpData.ofUtf8(((CharSequence) result).toString()), trailingHeaders); } return ResponseConverterFunction.fallthrough(); }
@Test public void testMessageConverterService() { AggregatedHttpMessage res; String body; // JSON for (final String path : Arrays.asList("/messageConverter/node/node", "/messageConverter/node/obj", "/messageConverter/obj/obj", "/messageConverter/obj/future")) { res = client.execute(HttpHeaders.of(HttpMethod.POST, path) .contentType(MediaType.JSON_UTF_8), "{\"name\":\"armeria\"}").aggregate().join(); assertThat(res.status()).isEqualTo(HttpStatus.OK); assertThat(res.headers().contentType().is(MediaType.JSON_UTF_8)).isTrue(); body = res.content().toStringUtf8(); assertThatJson(body).node("result").isStringEqualTo("success"); assertThatJson(body).node("from").isStringEqualTo("armeria"); } // custom(text protocol) res = client.execute(HttpHeaders.of(HttpMethod.POST, "/messageConverter/custom") .contentType(MediaType.PLAIN_TEXT_UTF_8), "armeria").aggregate().join(); assertThat(res.status()).isEqualTo(HttpStatus.OK); assertThat(res.headers().contentType().is(MediaType.PLAIN_TEXT_UTF_8)).isTrue(); assertThat(res.content().toStringUtf8()).isEqualTo("success:armeria"); }
final HttpHeaders unframedHeaders = HttpHeaders.copyOf(grpcResponse.headers()); if (grpcMediaType != null) { if (grpcMediaType.is(GrpcSerializationFormats.PROTO.mediaType())) { unframedHeaders.contentType(MediaType.PROTOBUF); } else if (grpcMediaType.is(GrpcSerializationFormats.JSON.mediaType())) { unframedHeaders.contentType(MediaType.JSON_UTF_8);