Polish ReactiveTypeHandler when checking wildcard ndjson subtype

This commit polishes the previous change, ensuring that if the request
uses a wildcard subtype with an ndjson suffix then the wildcard isn't
present in the response's Content-Type.

Insteand, in that case we would fall back to `applicatin/x-ndjson` (the
base ndjson media type), assuming that the requester is only interested
in the ndjson nature of the underlying representation and not in the
specific semantics of any subtype.

See commit 9332b3f
See gh-26817
This commit is contained in:
Simon Baslé
2023-05-26 15:16:39 +02:00
parent 4d8f6c1b41
commit 3f14ebc4cf
2 changed files with 122 additions and 16 deletions

View File

@@ -104,6 +104,54 @@ public class ReactiveTypeHandlerTests {
assertThat(this.handler.isReactiveType(String.class)).isFalse();
}
@Test
void findsConcreteStreamingMediaType() {
final List<MediaType> accept = List.of(
MediaType.ALL,
MediaType.parseMediaType("application/*+x-ndjson"),
MediaType.parseMediaType("application/vnd.myapp.v1+x-ndjson"));
assertThat(ReactiveTypeHandler.findConcreteStreamingMediaType(accept))
.isEqualTo(MediaType.APPLICATION_NDJSON);
}
@Test
void findsConcreteStreamingMediaType_vendorFirst() {
final List<MediaType> accept = List.of(
MediaType.ALL,
MediaType.parseMediaType("application/vnd.myapp.v1+x-ndjson"),
MediaType.parseMediaType("application/*+x-ndjson"),
MediaType.APPLICATION_NDJSON);
assertThat(ReactiveTypeHandler.findConcreteStreamingMediaType(accept))
.hasToString("application/vnd.myapp.v1+x-ndjson");
}
@Test
void findsConcreteStreamingMediaType_plainNdJsonFirst() {
final List<MediaType> accept = List.of(
MediaType.ALL,
MediaType.APPLICATION_NDJSON,
MediaType.parseMediaType("application/*+x-ndjson"),
MediaType.parseMediaType("application/vnd.myapp.v1+x-ndjson"));
assertThat(ReactiveTypeHandler.findConcreteStreamingMediaType(accept))
.isEqualTo(MediaType.APPLICATION_NDJSON);
}
@SuppressWarnings("deprecation")
@Test
void findsConcreteStreamingMediaType_plainStreamingJsonFirst() {
final List<MediaType> accept = List.of(
MediaType.ALL,
MediaType.APPLICATION_STREAM_JSON,
MediaType.parseMediaType("application/*+x-ndjson"),
MediaType.parseMediaType("application/vnd.myapp.v1+x-ndjson"));
assertThat(ReactiveTypeHandler.findConcreteStreamingMediaType(accept))
.isEqualTo(MediaType.APPLICATION_STREAM_JSON);
}
@Test
public void deferredResultSubscriberWithOneValue() throws Exception {
@@ -251,7 +299,7 @@ public class ReactiveTypeHandlerTests {
sink.tryEmitNext(bar2);
sink.tryEmitComplete();
assertThat(message.getHeaders().getContentType().toString()).isEqualTo("application/x-ndjson");
assertThat(message.getHeaders().getContentType()).hasToString("application/x-ndjson");
assertThat(emitterHandler.getValues()).isEqualTo(Arrays.asList(bar1, "\n", bar2, "\n"));
}
@@ -277,7 +325,33 @@ public class ReactiveTypeHandlerTests {
sink.tryEmitNext(bar2);
sink.tryEmitComplete();
assertThat(message.getHeaders().getContentType().toString()).isEqualTo("application/vnd.myapp.v1+x-ndjson");
assertThat(message.getHeaders().getContentType()).hasToString("application/vnd.myapp.v1+x-ndjson");
assertThat(emitterHandler.getValues()).isEqualTo(Arrays.asList(bar1, "\n", bar2, "\n"));
}
@Test
public void writeStreamJsonWithWildcardSubtype() throws Exception {
this.servletRequest.addHeader("Accept", "application/*+x-ndjson");
Sinks.Many<Bar> sink = Sinks.many().unicast().onBackpressureBuffer();
ResponseBodyEmitter emitter = handleValue(sink.asFlux(), Flux.class, forClass(Bar.class));
assertThat(emitter).as("emitter").isNotNull();
EmitterHandler emitterHandler = new EmitterHandler();
emitter.initialize(emitterHandler);
ServletServerHttpResponse message = new ServletServerHttpResponse(this.servletResponse);
emitter.extendResponse(message);
Bar bar1 = new Bar("foo");
Bar bar2 = new Bar("bar");
sink.tryEmitNext(bar1);
sink.tryEmitNext(bar2);
sink.tryEmitComplete();
assertThat(message.getHeaders().getContentType()).hasToString("application/x-ndjson");
assertThat(emitterHandler.getValues()).isEqualTo(Arrays.asList(bar1, "\n", bar2, "\n"));
}