我正在使用Spring启动,Spring MVC和Jackson。我正在编写一个RESTful API,如果只有请求包含参数prettify
,其中一个要求是对响应(json)进行美化。
例如,GET /examples/1
必须回答:{"id":1,"name":"example"}
和GET /examples/1?prettify
:
{
"id": 1,
"name": "example"
}
我知道我可以定义自己的ObjectMapper
,但我无法根据请求进行定制。我可以将spring.jackson.serialization.INDENT_OUTPUT
设置为true
但我无法显示响应不美化。
有人对此有所了解吗?
答案 0 :(得分:1)
好的,我已经完成了。
所以,这样做的方法是使用注入的Jackson2ObjectMapper来手动序列化响应:)
让我们看看简单的主要应用程序类:
@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;
}
}
一些休息控制器类:
@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;
}
}
和DTO课程:
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返回{"id":1,"name":"SomeName"}
而http://localhost:8080/testendpoint/1?pretify=true返回
{
"id" : 1,
"name" : "SomeName"
}
修改强> 如果你想为每个控制器使用它,请执行以下操作:
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;
}
}
现在添加新的拦截器:
@Configuration
public class InterceptorConfigurerAdapter extends WebMvcConfigurerAdapter{
@Bean
PretifyingInterceptor pretifyingInterceptor() {
return new PretifyingInterceptor();
}
@Override
public void addInterceptors(final InterceptorRegistry registry) {
registry.addInterceptor(pretifyingInterceptor())
.addPathPatterns("/**");
}
}
现在控制器看起来像:
@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:为了避免某些“拦截器之间的请求共享状态”,请定义具有范围request
的拦截器bean。
希望有所帮助:)