问题描述
我正在使用 Spring Boot、Spring MVC 和 Jackson.我正在编写一个 RESTful API,如果只有请求包含参数 prettify
,其中一个要求是美化响应 (json).
I am using Spring boot, Spring MVC and Jackson. I am writing a RESTful API and one of the requirements is to prettify the response (json) if only the request contains the parameter prettify
.
例如,GET/examples/1
必须回答:{"id":1,"name":"example"}
和 GET/examples/1?prettify
与:
For example, GET /examples/1
must answer with: {"id":1,"name":"example"}
, and GET /examples/1?prettify
with:
{
"id": 1,
"name": "example"
}
我知道我可以定义我自己的ObjectMapper
,但我不能根据请求来实现.我可以将 spring.jackson.serialization.INDENT_OUTPUT
设置为 true
但我无法显示 not 美化的响应.
I know I can define my own ObjectMapper
but I cannot make it depending on the request. I can set spring.jackson.serialization.INDENT_OUTPUT
to true
but I cannot display a response not prettified.
有人对此有什么想法吗?
Does someone have an idea about this?
推荐答案
好的,我已经搞定了.
所以,这样做的方法是使用注入的 Jackson2ObjectMapper 来手动序列化响应 :)
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;
}
}
一些休息控制器类:
@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 返回 >
http://localhost:8080/testendpoint/1 returns {"id":1,"name":"SomeName"}
while http://localhost:8080/testendpoint/1?pretify=true returns
{
"id" : 1,
"name" : "SomeName"
}
如果您想将它用于每个控制器,请执行以下操作:
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;
}
}
现在添加新的拦截器:
@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:为了避免某些Interceptor 的请求间共享状态",定义具有作用域 request
的 Interceptor bean.
To avoid some 'between-request shared state of Interceptor', define the Interceptor bean with scope request
.
希望有帮助:)
这篇关于根据 Jackson 和 Spring boot 的请求美化(或不美化)响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!