diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitter.java
index b28dba8c0be..a4536a4b9ca 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitter.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitter.java
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.springframework.web.servlet.mvc.method.annotation;
import java.io.IOException;
@@ -23,7 +24,6 @@ import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.util.Assert;
-
/**
* A controller method return value type for asynchronous request processing
* where one or more objects are written to the response. While
@@ -53,15 +53,12 @@ import org.springframework.util.Assert;
* emitter.complete();
*
*
- *
Note: this class is not thread-safe. Callers must ensure
- * that use from multiple threads is synchronized.
- *
* @author Rossen Stoyanchev
* @since 4.2
*/
public class ResponseBodyEmitter {
- private Handler handler;
+ private volatile Handler handler;
/* Cache for objects sent before handler is set. */
private final Map initHandlerCache = new LinkedHashMap(10);
@@ -124,7 +121,7 @@ public class ResponseBodyEmitter {
* @throws java.lang.IllegalStateException wraps any other errors
*/
public void send(Object object, MediaType mediaType) throws IOException {
- Assert.state(!this.complete, "ResponseBodyEmitter is already set complete.");
+ Assert.state(!this.complete, "ResponseBodyEmitter is already set complete");
sendInternal(object, mediaType);
}
@@ -132,9 +129,9 @@ public class ResponseBodyEmitter {
if (object == null) {
return;
}
- if (handler == null) {
+ if (this.handler == null) {
synchronized (this) {
- if (handler == null) {
+ if (this.handler == null) {
this.initHandlerCache.put(object, mediaType);
return;
}
@@ -143,11 +140,11 @@ public class ResponseBodyEmitter {
try {
this.handler.send(object, mediaType);
}
- catch(IOException ex){
+ catch (IOException ex){
this.handler.completeWithError(ex);
throw ex;
}
- catch(Throwable ex){
+ catch (Throwable ex){
this.handler.completeWithError(ex);
throw new IllegalStateException("Failed to send " + object, ex);
}
@@ -161,7 +158,7 @@ public class ResponseBodyEmitter {
public void complete() {
synchronized (this) {
this.complete = true;
- if (handler != null) {
+ if (this.handler != null) {
this.handler.complete();
}
}
@@ -176,7 +173,7 @@ public class ResponseBodyEmitter {
synchronized (this) {
this.complete = true;
this.failure = ex;
- if (handler != null) {
+ if (this.handler != null) {
this.handler.completeWithError(ex);
}
}
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitterReturnValueHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitterReturnValueHandler.java
index 5ed597d0e20..ef7f925d89e 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitterReturnValueHandler.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitterReturnValueHandler.java
@@ -13,18 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.springframework.web.servlet.mvc.method.annotation;
import java.io.IOException;
import java.io.OutputStream;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
import java.util.List;
-
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+
import org.springframework.core.MethodParameter;
import org.springframework.core.ResolvableType;
import org.springframework.http.HttpHeaders;
@@ -41,7 +40,6 @@ import org.springframework.web.context.request.async.WebAsyncUtils;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;
-
/**
* Supports return values of type {@link ResponseBodyEmitter} and also
* {@code ResponseEntity}.
@@ -61,6 +59,7 @@ public class ResponseBodyEmitterReturnValueHandler implements HandlerMethodRetur
this.messageConverters = messageConverters;
}
+
@Override
public boolean supportsReturnType(MethodParameter returnType) {
if (ResponseBodyEmitter.class.isAssignableFrom(returnType.getParameterType())) {
@@ -121,13 +120,11 @@ public class ResponseBodyEmitterReturnValueHandler implements HandlerMethodRetur
private final DeferredResult> deferredResult;
-
public HttpMessageConvertingHandler(ServerHttpResponse outputMessage, DeferredResult> deferredResult) {
this.outputMessage = outputMessage;
this.deferredResult = deferredResult;
}
-
@Override
public void send(Object data, MediaType mediaType) throws IOException {
sendInternal(data, mediaType);
@@ -145,7 +142,7 @@ public class ResponseBodyEmitterReturnValueHandler implements HandlerMethodRetur
return;
}
}
- throw new IllegalArgumentException("No suitable converter for " + data);
+ throw new IllegalArgumentException("No suitable converter for " + data.getClass());
}
@Override
@@ -170,13 +167,11 @@ public class ResponseBodyEmitterReturnValueHandler implements HandlerMethodRetur
private final HttpHeaders mutableHeaders = new HttpHeaders();
-
public StreamingServletServerHttpResponse(ServerHttpResponse delegate) {
this.delegate = delegate;
this.mutableHeaders.putAll(delegate.getHeaders());
}
-
@Override
public void setStatusCode(HttpStatus status) {
this.delegate.setStatusCode(status);
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SseEmitter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SseEmitter.java
index 874af6c9526..6f3981d228e 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SseEmitter.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SseEmitter.java
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.springframework.web.servlet.mvc.method.annotation;
import java.io.IOException;
@@ -26,9 +27,7 @@ import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpResponse;
/**
- * A specialization of
- * {@link org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter
- * ResponseBodyEmitter} for sending
+ * A specialization of {@link ResponseBodyEmitter} for sending
* Server-Sent Events .
*
* @author Rossen Stoyanchev
@@ -36,7 +35,7 @@ import org.springframework.http.server.ServerHttpResponse;
*/
public class SseEmitter extends ResponseBodyEmitter {
- public static final MediaType TEXT_PLAIN = new MediaType("text", "plain", Charset.forName("UTF-8"));
+ static final MediaType TEXT_PLAIN = new MediaType("text", "plain", Charset.forName("UTF-8"));
@Override
@@ -51,7 +50,6 @@ public class SseEmitter extends ResponseBodyEmitter {
/**
* Send the object formatted as a single SSE "data" line. It's equivalent to:
*
- *
* // static import of SseEmitter.*
*
* SseEmitter emitter = new SseEmitter();
@@ -69,7 +67,6 @@ public class SseEmitter extends ResponseBodyEmitter {
/**
* Send the object formatted as a single SSE "data" line. It's equivalent to:
*
- *
* // static import of SseEmitter.*
*
* SseEmitter emitter = new SseEmitter();
@@ -91,7 +88,6 @@ public class SseEmitter extends ResponseBodyEmitter {
/**
* Send an SSE event prepared with the given builder. For example:
*
- *
* // static import of SseEmitter
*
* SseEmitter emitter = new SseEmitter();
@@ -108,6 +104,7 @@ public class SseEmitter extends ResponseBodyEmitter {
}
}
+
public static SseEventBuilder event() {
return new DefaultSseEventBuilder();
}
@@ -156,6 +153,7 @@ public class SseEmitter extends ResponseBodyEmitter {
Map build();
}
+
/**
* Default implementation of SseEventBuilder.
*/
@@ -165,7 +163,6 @@ public class SseEmitter extends ResponseBodyEmitter {
private StringBuilder sb;
-
@Override
public SseEventBuilder comment(String comment) {
append(":").append(comment != null ? comment : "").append("\n");