根据Jackson和Spring启动

时间:2016-02-07 15:59:42

标签: json spring spring-mvc spring-boot jackson

我正在使用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但我无法显示响应美化。

有人对此有所了解吗?

1 个答案:

答案 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。

希望有所帮助:)