根据 Jackson 和 Spring boot 的请求美化(或不美化)响应 [英] Prettify (or not) the response depending on the request with Jackson and Spring boot

查看:58
本文介绍了根据 Jackson 和 Spring boot 的请求美化(或不美化)响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 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 的请求美化(或不美化)响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆