Skip to content

Commit 5700d65

Browse files
committed
Append "data:" after line breaks for SSE JSON data fields
Issue: SPR-14899
1 parent e707c40 commit 5700d65

File tree

2 files changed

+37
-5
lines changed

2 files changed

+37
-5
lines changed

spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,14 @@
2626
import com.fasterxml.jackson.core.JsonEncoding;
2727
import com.fasterxml.jackson.core.JsonGenerator;
2828
import com.fasterxml.jackson.core.JsonProcessingException;
29+
import com.fasterxml.jackson.core.PrettyPrinter;
30+
import com.fasterxml.jackson.core.util.DefaultIndenter;
2931
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
3032
import com.fasterxml.jackson.databind.JavaType;
3133
import com.fasterxml.jackson.databind.JsonMappingException;
3234
import com.fasterxml.jackson.databind.ObjectMapper;
3335
import com.fasterxml.jackson.databind.ObjectWriter;
36+
import com.fasterxml.jackson.databind.SerializationConfig;
3437
import com.fasterxml.jackson.databind.SerializationFeature;
3538
import com.fasterxml.jackson.databind.ser.FilterProvider;
3639
import com.fasterxml.jackson.databind.type.TypeFactory;
@@ -63,27 +66,36 @@ public abstract class AbstractJackson2HttpMessageConverter extends AbstractGener
6366

6467
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
6568

69+
private static final MediaType TEXT_EVENT_STREAM = new MediaType("text", "event-stream");
70+
6671

6772
protected ObjectMapper objectMapper;
6873

6974
private Boolean prettyPrint;
7075

76+
private PrettyPrinter ssePrettyPrinter;
77+
7178

7279
protected AbstractJackson2HttpMessageConverter(ObjectMapper objectMapper) {
73-
this.objectMapper = objectMapper;
74-
setDefaultCharset(DEFAULT_CHARSET);
80+
init(objectMapper);
7581
}
7682

7783
protected AbstractJackson2HttpMessageConverter(ObjectMapper objectMapper, MediaType supportedMediaType) {
7884
super(supportedMediaType);
79-
this.objectMapper = objectMapper;
80-
setDefaultCharset(DEFAULT_CHARSET);
85+
init(objectMapper);
8186
}
8287

8388
protected AbstractJackson2HttpMessageConverter(ObjectMapper objectMapper, MediaType... supportedMediaTypes) {
8489
super(supportedMediaTypes);
90+
init(objectMapper);
91+
}
92+
93+
protected void init(ObjectMapper objectMapper) {
8594
this.objectMapper = objectMapper;
8695
setDefaultCharset(DEFAULT_CHARSET);
96+
DefaultPrettyPrinter prettyPrinter = new DefaultPrettyPrinter();
97+
prettyPrinter.indentObjectsWith(new DefaultIndenter(" ", "\ndata:"));
98+
this.ssePrettyPrinter = prettyPrinter;
8799
}
88100

89101

@@ -233,7 +245,8 @@ private Object readJavaType(JavaType javaType, HttpInputMessage inputMessage) {
233245
protected void writeInternal(Object object, Type type, HttpOutputMessage outputMessage)
234246
throws IOException, HttpMessageNotWritableException {
235247

236-
JsonEncoding encoding = getJsonEncoding(outputMessage.getHeaders().getContentType());
248+
MediaType contentType = outputMessage.getHeaders().getContentType();
249+
JsonEncoding encoding = getJsonEncoding(contentType);
237250
JsonGenerator generator = this.objectMapper.getFactory().createGenerator(outputMessage.getBody(), encoding);
238251
try {
239252
writePrefix(generator, object);
@@ -264,6 +277,11 @@ else if (filters != null) {
264277
if (javaType != null && javaType.isContainerType()) {
265278
objectWriter = objectWriter.forType(javaType);
266279
}
280+
SerializationConfig config = objectWriter.getConfig();
281+
if (contentType != null && contentType.isCompatibleWith(TEXT_EVENT_STREAM) &&
282+
config.isEnabled(SerializationFeature.INDENT_OUTPUT)) {
283+
objectWriter = objectWriter.with(this.ssePrettyPrinter);
284+
}
267285
objectWriter.writeValue(generator, value);
268286

269287
writeSuffix(generator, object);

spring-web/src/test/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverterTests.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,20 @@ public void prettyPrint() throws Exception {
225225
assertEquals("{" + NEWLINE_SYSTEM_PROPERTY + " \"name\" : \"Jason\"" + NEWLINE_SYSTEM_PROPERTY + "}", result);
226226
}
227227

228+
@Test
229+
public void prettyPrintWithSse() throws Exception {
230+
MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
231+
outputMessage.getHeaders().setContentType(new MediaType("text", "event-stream"));
232+
PrettyPrintBean bean = new PrettyPrintBean();
233+
bean.setName("Jason");
234+
235+
this.converter.setPrettyPrint(true);
236+
this.converter.writeInternal(bean, null, outputMessage);
237+
String result = outputMessage.getBodyAsString(Charset.forName("UTF-8"));
238+
239+
assertEquals("{\ndata: \"name\" : \"Jason\"\ndata:}", result);
240+
}
241+
228242
@Test
229243
public void prefixJson() throws Exception {
230244
MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();

0 commit comments

Comments
 (0)