diff --git a/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java index f3942f68f4..f14c82737a 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java @@ -26,11 +26,14 @@ import java.util.concurrent.atomic.AtomicReference; import com.fasterxml.jackson.core.JsonEncoding; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.PrettyPrinter; +import com.fasterxml.jackson.core.util.DefaultIndenter; import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectWriter; +import com.fasterxml.jackson.databind.SerializationConfig; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.ser.FilterProvider; import com.fasterxml.jackson.databind.type.TypeFactory; @@ -63,27 +66,36 @@ public abstract class AbstractJackson2HttpMessageConverter extends AbstractGener public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); + private static final MediaType TEXT_EVENT_STREAM = new MediaType("text", "event-stream"); + protected ObjectMapper objectMapper; private Boolean prettyPrint; + private PrettyPrinter ssePrettyPrinter; + protected AbstractJackson2HttpMessageConverter(ObjectMapper objectMapper) { - this.objectMapper = objectMapper; - setDefaultCharset(DEFAULT_CHARSET); + init(objectMapper); } protected AbstractJackson2HttpMessageConverter(ObjectMapper objectMapper, MediaType supportedMediaType) { super(supportedMediaType); - this.objectMapper = objectMapper; - setDefaultCharset(DEFAULT_CHARSET); + init(objectMapper); } protected AbstractJackson2HttpMessageConverter(ObjectMapper objectMapper, MediaType... supportedMediaTypes) { super(supportedMediaTypes); + init(objectMapper); + } + + protected void init(ObjectMapper objectMapper) { this.objectMapper = objectMapper; setDefaultCharset(DEFAULT_CHARSET); + DefaultPrettyPrinter prettyPrinter = new DefaultPrettyPrinter(); + prettyPrinter.indentObjectsWith(new DefaultIndenter(" ", "\ndata:")); + this.ssePrettyPrinter = prettyPrinter; } @@ -233,7 +245,8 @@ public abstract class AbstractJackson2HttpMessageConverter extends AbstractGener protected void writeInternal(Object object, Type type, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException { - JsonEncoding encoding = getJsonEncoding(outputMessage.getHeaders().getContentType()); + MediaType contentType = outputMessage.getHeaders().getContentType(); + JsonEncoding encoding = getJsonEncoding(contentType); JsonGenerator generator = this.objectMapper.getFactory().createGenerator(outputMessage.getBody(), encoding); try { writePrefix(generator, object); @@ -264,6 +277,11 @@ public abstract class AbstractJackson2HttpMessageConverter extends AbstractGener if (javaType != null && javaType.isContainerType()) { objectWriter = objectWriter.forType(javaType); } + SerializationConfig config = objectWriter.getConfig(); + if (contentType != null && contentType.isCompatibleWith(TEXT_EVENT_STREAM) && + config.isEnabled(SerializationFeature.INDENT_OUTPUT)) { + objectWriter = objectWriter.with(this.ssePrettyPrinter); + } objectWriter.writeValue(generator, value); writeSuffix(generator, object); diff --git a/spring-web/src/test/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverterTests.java b/spring-web/src/test/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverterTests.java index e2b15b0861..de4ebe2fd8 100644 --- a/spring-web/src/test/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverterTests.java +++ b/spring-web/src/test/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverterTests.java @@ -225,6 +225,20 @@ public class MappingJackson2HttpMessageConverterTests { assertEquals("{" + NEWLINE_SYSTEM_PROPERTY + " \"name\" : \"Jason\"" + NEWLINE_SYSTEM_PROPERTY + "}", result); } + @Test + public void prettyPrintWithSse() throws Exception { + MockHttpOutputMessage outputMessage = new MockHttpOutputMessage(); + outputMessage.getHeaders().setContentType(new MediaType("text", "event-stream")); + PrettyPrintBean bean = new PrettyPrintBean(); + bean.setName("Jason"); + + this.converter.setPrettyPrint(true); + this.converter.writeInternal(bean, null, outputMessage); + String result = outputMessage.getBodyAsString(Charset.forName("UTF-8")); + + assertEquals("{\ndata: \"name\" : \"Jason\"\ndata:}", result); + } + @Test public void prefixJson() throws Exception { MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();