Spring MVC:为每个响应添加新行

5

考虑一个简单的@RestController,返回一个Map:

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

这个很好用,可以将Map转换成JSON。

但是,在终端中使用curl请求时,光标会停留在JSON的末尾,这样操作起来不太方便。我们之前的实现方法总是在每个JSON的末尾返回\n。有没有办法让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个回答

2
最终通过 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())
    }
}

0

你可以使用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
}

我正在寻找一种通用解决方案,也就是一个 @ConfigurationFilter,可以处理这个问题。你的最后一部分正是我所需要的,但我仍然不确定如何实现它。 - Vojtěch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接