Hi guys,

I'm currently developing a feature in which I rely on Spring's HttpMessageConverter infrastructure and facing a necessity to have control over the configuration of PrettyPrinter instance used in MappingJackson2HttpMessageConverter. E.g. have different indentation. The PrettyPrinter reference is currently private to converter instance and has no accessors available to sub-classes: https://github.com/spring-projects/spring-framework/blob/4a9c7e631c60a12f3426d42143e9e27be0bf68ab/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java#L110 Every other aspect of behavior of MappingJackson2HttpMessageConverter is totally OK to me.

I thought what if you'll start to configure ObjectWriter instance with default pretty printer from Jackson's ObjectMapper settings? I.e. here https://github.com/spring-projects/spring-framework/blob/4a9c7e631c60a12f3426d42143e9e27be0bf68ab/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java#L452 instead of tying it to your very own pretty printer do: objectWriter = objectWriter.withDefaultPrettyPrinter(); and make ssePrettyPrinter to be the default one in org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter#init(ObjectMapper), which is protected and therefore allowed to override. Thus you'll preserving current behavior simultaneously with allowing customization of pretty printer by external consumers.

Or propose your own variant for achieving the same!

We're stuck here at Spring Framework 4.3.25 so I'll have to solve my problem in some other way and won't directly benefit from the resolution of this issue. Still, I think the idea is quite interesting, don't you think so?

Thanks, Dzmitry

Comment From: sbrannen

Hi @dzmitry-chuchva,

Thanks for opening your first issue for the Spring Framework.

At a glance, I think that sounds reasonable, and we'll discuss it within the team.

Comment From: dzmitry-chuchva

Hi @sbrannen,

That's right, it my first one. And just 40 minutes after creation of it I think now it may be not an issue :(

I've just tested MappingJackson2HttpMessageConverter constructed with ObjectMapper instance which I've prepared with custom default pretty printer:

class MyMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {
        public MyMappingJackson2HttpMessageConverter() {
            super(Jackson2ObjectMapperBuilder.json()
                    .build()
                    .setDefaultPrettyPrinter(new DefaultPrettyPrinter()
                            .withObjectIndenter(new DefaultIndenter("    ", "\n"))));
            setPrettyPrint(true);
        }
}

and looks like my custom pretty printer gets applied! I do not understand the exact mechanism of this though. I was sure it would get overridden by internal private PrettyPrinter instance of MappingJackson2HttpMessageConverter.

I'm ready to close this issue if you do not mind.

Comment From: sbrannen

If selectObjectMapper(...) returns this.defaultObjectMapper, then your PrettyPrinter will be used; whereas, the internal private ssePrettyPrinter will be used with any ObjectMapper if contentType.isCompatibleWith(MediaType.TEXT_EVENT_STREAM) is true.

The latter applies to your custom configured ObjectMapper as well. If you are writing MediaType.TEXT_EVENT_STREAM, your custom configured PrettyPrinter will be overridden by the ssePrettyPrinter.

In summary, I think your solution is fine for the default object mapper, but I think it is a bit odd that Spring will override a custom configured PrettyPrinter for SSE. So perhaps we should rethink the logic for that.

Comment From: rstoyanchev

Not only if the content-type is SSE but also when indentation is enabled. For those cases we have to ensure correct SSE formatting by prefixing each new line like this:

data: {\n
data: "userId" : "myuser",\n
data: "objectId" : "s1"\n
data: }\n\n

In other words, this is by design.