@ -1,5 +1,5 @@
@@ -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 .
@ -18,7 +18,7 @@ package org.springframework.http.codec;
@@ -18,7 +18,7 @@ package org.springframework.http.codec;
import java.nio.charset.StandardCharsets ;
import java.time.Duration ;
import java.util.ArrayLi st ;
import java.util.Arrays ;
import java.util.Collections ;
import java.util.List ;
import java.util.Map ;
@ -112,7 +112,7 @@ public class ServerSentEventHttpMessageWriter implements HttpMessageWriter<Objec
@@ -112,7 +112,7 @@ public class ServerSentEventHttpMessageWriter implements HttpMessageWriter<Objec
}
private Flux < Publisher < DataBuffer > > encode ( Publisher < ? > input , ResolvableType elementType ,
MediaType mediaType , DataBufferFactory bu fferF actory, Map < String , Object > hints ) {
MediaType mediaType , DataBufferFactory factory , Map < String , Object > hints ) {
ResolvableType dataType = ( ServerSentEvent . class . isAssignableFrom ( elementType . toClass ( ) ) ?
elementType . getGeneric ( ) : elementType ) ;
@ -144,13 +144,35 @@ public class ServerSentEventHttpMessageWriter implements HttpMessageWriter<Objec
@@ -144,13 +144,35 @@ public class ServerSentEventHttpMessageWriter implements HttpMessageWriter<Objec
sb . append ( "data:" ) ;
}
Mono < DataBuffer > bufferMono = Mono . fromCallable ( ( ) - >
bufferFactory . join ( encodeEvent ( sb , data , dataType , mediaType , bufferFactory , hints ) ) ) ;
Flux < DataBuffer > result ;
if ( data = = null ) {
result = Flux . just ( encodeText ( sb + "\n" , mediaType , factory ) ) ;
}
else if ( data instanceof String ) {
data = StringUtils . replace ( ( String ) data , "\n" , "\ndata:" ) ;
result = Flux . just ( encodeText ( sb + ( String ) data + "\n\n" , mediaType , factory ) ) ;
}
else {
result = encodeEvent ( sb . toString ( ) , data , dataType , mediaType , factory , hints ) ;
}
return bufferMono . doOnDiscard ( PooledDataBuffer . class , DataBufferUtils : : release ) ;
return result . doOnDiscard ( PooledDataBuffer . class , DataBufferUtils : : release ) ;
} ) ;
}
@SuppressWarnings ( "unchecked" )
private < T > Flux < DataBuffer > encodeEvent ( String eventContent , T data , ResolvableType dataType ,
MediaType mediaType , DataBufferFactory factory , Map < String , Object > hints ) {
if ( this . encoder = = null ) {
throw new CodecException ( "No SSE encoder configured and the data is not String." ) ;
}
return Flux . just ( factory . join ( Arrays . asList (
encodeText ( eventContent , mediaType , factory ) ,
( ( Encoder < T > ) this . encoder ) . encodeValue ( data , factory , dataType , mediaType , hints ) ,
encodeText ( "\n\n" , mediaType , factory ) ) ) ) ;
}
private void writeField ( String fieldName , Object fieldValue , StringBuilder sb ) {
sb . append ( fieldName ) ;
sb . append ( ':' ) ;
@ -158,29 +180,6 @@ public class ServerSentEventHttpMessageWriter implements HttpMessageWriter<Objec
@@ -158,29 +180,6 @@ public class ServerSentEventHttpMessageWriter implements HttpMessageWriter<Objec
sb . append ( "\n" ) ;
}
@SuppressWarnings ( "unchecked" )
private < T > List < DataBuffer > encodeEvent ( CharSequence markup , @Nullable T data , ResolvableType dataType ,
MediaType mediaType , DataBufferFactory factory , Map < String , Object > hints ) {
List < DataBuffer > result = new ArrayList < > ( 4 ) ;
result . add ( encodeText ( markup , mediaType , factory ) ) ;
if ( data ! = null ) {
if ( data instanceof String ) {
String dataLine = StringUtils . replace ( ( String ) data , "\n" , "\ndata:" ) + "\n" ;
result . add ( encodeText ( dataLine , mediaType , factory ) ) ;
}
else if ( this . encoder = = null ) {
throw new CodecException ( "No SSE encoder configured and the data is not String." ) ;
}
else {
result . add ( ( ( Encoder < T > ) this . encoder ) . encodeValue ( data , factory , dataType , mediaType , hints ) ) ;
result . add ( encodeText ( "\n" , mediaType , factory ) ) ;
}
}
result . add ( encodeText ( "\n" , mediaType , factory ) ) ;
return result ;
}
private DataBuffer encodeText ( CharSequence text , MediaType mediaType , DataBufferFactory bufferFactory ) {
Assert . notNull ( mediaType . getCharset ( ) , "Expected MediaType with charset" ) ;
byte [ ] bytes = text . toString ( ) . getBytes ( mediaType . getCharset ( ) ) ;