Ok, I've done it.
So, the way to do it, is to use injected Jackson2ObjectMapper to manually serialize response :)
Lets look on simple main application class:
@SpringBootApplication
public class StackoverflowApplication {
public static void main(String[] args) {
SpringApplication.run(StackoverflowApplication.class, args);
}
@Bean
public Jackson2ObjectMapperBuilder objectMapperBuilder() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.indentOutput(true);
return builder;
}
}
Some rest controller class:
@RestController
public class TestRestController {
private static final Logger LOGGER = Logger.getLogger(TestRestController.class);
@Autowired
Jackson2ObjectMapperBuilder objectMapperBuilder;
@RequestMapping(value = "/testendpoint/{somevalue}", method = RequestMethod.GET, produces="application/json")
public @ResponseBody String customersLastVisit(@PathVariable(value = "somevalue") Integer number,
@RequestParam(value = "pretify", defaultValue = "false") Boolean pretify) throws JsonProcessingException {
if (pretify) {
LOGGER.info("Pretify response!");
objectMapperBuilder.indentOutput(true);
}
else {
objectMapperBuilder.indentOutput(false);
}
ObjectMapper mapper = objectMapperBuilder.build();
String jsonResponse = mapper.writeValueAsString(new TestDTO());
return jsonResponse;
}
}
And DTO class:
public class TestDTO implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String name;
public TestDTO() {
super();
id = new Integer(1);
name = new String("SomeName");
}
//getters, setters etc ...
}
http://localhost:8080/testendpoint/1 returns {"id":1,"name":"SomeName"}
while http://localhost:8080/testendpoint/1?pretify=true returns
{
"id" : 1,
"name" : "SomeName"
}
Edit:
If you want to use it for every controller do like this:
public class PretifyingInterceptor extends HandlerInterceptorAdapter {
private static final Logger LOGGER = Logger.getLogger(PretifyingInterceptor.class);
@Autowired
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
String pretify = request.getParameter("pretify");
Boolean isPretify = Boolean.parseBoolean(pretify);
LOGGER.info("Should be pretified: " + isPretify);
if (isPretify) {
mappingJackson2HttpMessageConverter.setPrettyPrint(true);
}
else {
mappingJackson2HttpMessageConverter.setPrettyPrint(false);
}
return true;
}
}
Now add new interceptor:
@Configuration
public class InterceptorConfigurerAdapter extends WebMvcConfigurerAdapter{
@Bean
PretifyingInterceptor pretifyingInterceptor() {
return new PretifyingInterceptor();
}
@Override
public void addInterceptors(final InterceptorRegistry registry) {
registry.addInterceptor(pretifyingInterceptor())
.addPathPatterns("/**");
}
}
And now controller can look like:
@RequestMapping(value = "/testendpoint/{somevalue}", method = RequestMethod.GET, produces = "application/json")
public @ResponseBody TestDTO customersLastVisit(@PathVariable(value = "somevalue") Integer number,
@RequestParam(value = "pretify", defaultValue = "false") Boolean pretify) throws JsonProcessingException {
return new TestDTO();
}
Edit2: To avoid some 'between-request shared state of Interceptor', define the Interceptor bean with scope request
.
Hope that helps :)