Add NDJSON and deprecate application/stream+json
Closes gh-21283
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,7 @@ package org.springframework.web.servlet.mvc.method.annotation;
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -73,8 +74,12 @@ class ReactiveTypeHandler {
|
||||
|
||||
private static final long STREAMING_TIMEOUT_VALUE = -1;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private static final List<MediaType> JSON_STREAMING_MEDIA_TYPES =
|
||||
Arrays.asList(MediaType.APPLICATION_NDJSON, MediaType.APPLICATION_STREAM_JSON);
|
||||
|
||||
private static final Log logger = LogFactory.getLog(ReactiveTypeHandler.class);
|
||||
|
||||
private static Log logger = LogFactory.getLog(ReactiveTypeHandler.class);
|
||||
|
||||
private final ReactiveAdapterRegistry adapterRegistry;
|
||||
|
||||
@@ -144,11 +149,15 @@ class ReactiveTypeHandler {
|
||||
new TextEmitterSubscriber(emitter, this.taskExecutor).connect(adapter, returnValue);
|
||||
return emitter;
|
||||
}
|
||||
if (mediaTypes.stream().anyMatch(MediaType.APPLICATION_STREAM_JSON::includes)) {
|
||||
logExecutorWarning(returnType);
|
||||
ResponseBodyEmitter emitter = getEmitter(MediaType.APPLICATION_STREAM_JSON);
|
||||
new JsonEmitterSubscriber(emitter, this.taskExecutor).connect(adapter, returnValue);
|
||||
return emitter;
|
||||
for (MediaType type : mediaTypes) {
|
||||
for (MediaType streamingType : JSON_STREAMING_MEDIA_TYPES) {
|
||||
if (streamingType.includes(type)) {
|
||||
logExecutorWarning(returnType);
|
||||
ResponseBodyEmitter emitter = getEmitter(streamingType);
|
||||
new JsonEmitterSubscriber(emitter, this.taskExecutor).connect(adapter, returnValue);
|
||||
return emitter;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -250,7 +250,7 @@
|
||||
By default, a SimpleAsyncTaskExecutor is used which does not re-use threads and is not recommended for production.
|
||||
|
||||
As of 5.0 this executor is also used when a controller returns a reactive type that does streaming
|
||||
(e.g. "text/event-stream" or "application/stream+json") for the blocking writes to the
|
||||
(e.g. "text/event-stream" or "application/x-ndjson") for the blocking writes to the
|
||||
"javax.servlet.ServletOutputStream".
|
||||
|
||||
]]></xsd:documentation>
|
||||
|
||||
@@ -225,7 +225,7 @@ public class ReactiveTypeHandlerTests {
|
||||
@Test
|
||||
public void writeStreamJson() throws Exception {
|
||||
|
||||
this.servletRequest.addHeader("Accept", "application/stream+json");
|
||||
this.servletRequest.addHeader("Accept", "application/x-ndjson");
|
||||
|
||||
Sinks.StandaloneFluxSink<Bar> sink = Sinks.unicast();
|
||||
ResponseBodyEmitter emitter = handleValue(sink.asFlux(), Flux.class, forClass(Bar.class));
|
||||
@@ -243,7 +243,7 @@ public class ReactiveTypeHandlerTests {
|
||||
sink.next(bar2);
|
||||
sink.complete();
|
||||
|
||||
assertThat(message.getHeaders().getContentType().toString()).isEqualTo("application/stream+json");
|
||||
assertThat(message.getHeaders().getContentType().toString()).isEqualTo("application/x-ndjson");
|
||||
assertThat(emitterHandler.getValues()).isEqualTo(Arrays.asList(bar1, "\n", bar2, "\n"));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user