Jens Goldhammer Jens Goldhammer - 7 months ago 40
Java Question

How to enable dynamic pretty print of json based on http request header in Spring MVC?

I want to pretty print json responses from Spring MVC Restcontrollers dynamically based on a http parameter (like suggested here: http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api#pretty-print-gzip).

I have found configurations for pretty print it by static configuration, but not how to do that dynamically?

When using Spring MVC for REST, how do you enable Jackson to pretty-print rendered JSON?

Any idea how to do that?

Answer

Introducing A New Media Type


You can define a new Media Type, say, application/pretty+json and register a new HttpMessageConverter that converts to that Media Type. In fact, if client sends a request with Accept: application/pretty+json header, our new HttpMessageConverter will write the response, Otherwise, the plain old MappingJackson2HttpMessageConverter would do that.

So, extends the MappingJackson2HttpMessageConverter like following:

public class PrettyPrintJsonConverter extends MappingJackson2HttpMessageConverter {
    public PrettyPrintJsonConverter() {
        setPrettyPrint(true);
    }

    @Override
    public List<MediaType> getSupportedMediaTypes() {
        return Collections.singletonList(new MediaType("application", "pretty+json"));
    }

    @Override
    public boolean canWrite(Class<?> clazz, MediaType mediaType) {
        boolean canWrite = super.canWrite(clazz, mediaType);
        boolean canWritePrettily = mediaType != null && 
                                   mediaType.getSubtype().equals("pretty+json");

        return canWrite && canWritePrettily;
    }
}

That setPrettyPrint(true) in constructor will do the trick for us. Then we should register this HttpMessageConverter:

@EnableWebMvc
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(new PrettyPrintJsonConverter());
    }
}

As i said, if client send a request with application/pretty+json Accept header, our PrettyPrintJsonConverter will write the JSON representation Prettily. Otherwise, MappingJackson2HttpMessageConverter would write a compact JSON to the response body.

You can achieve the same with a ResponseBodyAdvice or even Interceptors but in my opinion, registering a brand new HttpMessageConverter is the better approach.

Comments