如何修改WebMVC.fn RouterFunction响应的Content-Type响应头?
这个问题我之前也碰到过,Spring WebFlux里直接返回JSON格式的字符串时,框架会默认把Content-Type设为text/plain,给你两个可行的解决办法:
解决方法1:在处理器函数中直接指定Content-Type
这是最直接的方式,不用依赖过滤器。你可以在MyHandler的getDefinitions方法里,构建ServerResponse时就明确设置Content-Type为application/json:
public Mono<ServerResponse> getDefinitions() { // 你的JSON格式字符串 String responseString = "{\"data\": \"sample definitions\"}"; return ServerResponse.ok() .contentType(MediaType.APPLICATION_JSON) .bodyValue(responseString); }
这样返回的响应就会自动带上正确的Content-Type头,不需要再通过过滤器修改,逻辑也更清晰。
解决方法2:通过过滤器修改响应头(如果必须用过滤器的话)
如果因为业务需求必须用过滤器来统一处理,那你需要先从原响应中提取响应体,再重新构建一个带有正确Content-Type的响应。因为ServerResponse.from(serverResponse)只会复制状态码和原有头信息,不会包含响应体,所以得用bodyToMono来获取体内容:
@Bean public RouterFunction<ServerResponse> infoRouter(MyHandler myHandler) { return nest( path("info"), route().GET("definitions", __ -> myHandler.getDefinitions()).build() ).filter(HandlerFilterFunction.ofResponseProcessor((serverRequest, serverResponse) -> // 从原响应中提取字符串类型的响应体 serverResponse.bodyToMono(String.class) .map(responseBody -> // 基于原响应的状态和头信息,重新构建响应并设置Content-Type ServerResponse.from(serverResponse) .contentType(MediaType.APPLICATION_JSON) .bodyValue(responseBody) .build() ) )); }
这里的核心是先用bodyToMono(String.class)拿到原响应的JSON字符串,再基于原响应的基础配置(比如状态码),添加application/json的Content-Type头,最后把响应体重新放进去。
另外提一句:如果你的响应内容本来就是Java对象,推荐直接用bodyValue(yourObject),框架会自动帮你序列化为JSON并设置正确的Content-Type,还能避免手动拼接JSON字符串容易出错的问题。
内容的提问来源于stack exchange,提问作者aksh1618
相关产品推荐
相关产品推荐

