代码之家  ›  专栏  ›  技术社区  ›  Vojtěch

Spring MVC:向每个响应追加新行

  •  5
  • Vojtěch  · 技术社区  · 6 年前

    考虑simple@RestController,返回一个映射:

    @GetMapping("/foo")
    public ResponseEntity<Map<String, Object>> foo() {
        Map<String, Any> map = HashMap<>();
        map.put(...);
        return ResponseEntity(map, HttpStatus.OK);
    }
    

    这很好地工作,并将映射返回为JSON。

    但是,当你 curl 终端中的请求,光标停留在JSON的末尾,不幸的是,使用它会感到不舒服。我们以前的实现总是返回 \n 在每个JSON的末尾。有没有办法让Spring附加 \n个 也?

    编辑

    我试图实现格式化程序:

    private inner class MapFormatter : Formatter<Map<*, *>> {
        override fun parse(payload: String, locale: Locale): Map<*, *> {
            return Gson().fromJson(payload, Map::class)
        }
    
        override fun print(payload: Map<*, *>, locale: Locale): String {
            return Gson().toJson(payload) + "\n"
        }
    }
    

    并加入:

    override fun addFormatters(registry: FormatterRegistry) {
        registry.addFormatter(MapFormatter())
    }
    

    不幸的是,它从来没有被调用,我想格式化程序是为了别的目的。

    2 回复  |  直到 6 年前
        1
  •  2
  •   Vojtěch    6 年前

    最后通过 HttpMessageConverter :

    class GsonHttpMessageConverter : AbstractHttpMessageConverter<Map<String, Any?>>(
            MediaType("application", "json", Charset.forName("UTF-8"))) {
    
        override fun readInternal(clazz: Class<out Map<String, Any?>>, inputMessage: HttpInputMessage)
                = Gson().fromJson(IOUtils.toString(inputMessage.body, "UTF-8"), clazz)
    
        override fun supports(clazz: Class<*>) = Map::class.java.isAssignableFrom(clazz)
    
        override fun writeInternal(payload: Map<String, Any?>, outputMessage: HttpOutputMessage) {   
            outputMessage.body.write(Gson().toJson(payload) + "\n".toByteArray())
        }
    }
    
        2
  •  0
  •   Doctor Parameter    6 年前

    您可以使用Jackson序列化到一个字符串,然后附加您想要的内容并使其成为响应实体的主体。

    像这样的:

    //Somewhere in the class fields
    private final ObjectMapper mapper = new ObjectMapper();
    
    @GetMapping("/foo")
    public ResponseEntity<Map<String, Object>> foo() {
        Map<String, Any> map = HashMap<>();
        map.put(...);
        return ResponseEntity(mapper.writeValueAsString(map) + "/n", HttpStatus.OK);
    }
    

    然而,正确的答案应该是让您所使用的解析JSON的工具按您所希望的方式显示它。因为现在你必须要添加所有的复杂性。

    另一个解决方案是通过设置漂亮的打印机来“漂亮地打印”JSON: https://fasterxml.github.io/jackson-databind/javadoc/2.7/com/fasterxml/jackson/databind/ObjectMapper.html#setDefaultPrettyPrinter(com.fasterxml.jackson.core.PrettyPrinter) .

    另外,如果要执行此操作,请在构建控制器/服务时使用类似于这样的方法在spring级别设置:

    //Need to look at the documentation and figure out how to set this.    
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer mapperBuilderCustomizer() {
        return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder
    }