如何使用org.springframework.format.Formatter.print()实现返回值自动格式化
结论
默认配置下,你注册的DateFormatter不会自动对@RestController的Date类型返回值调用print方法做格式化,不过不需要你在每个接口手动注入FormattingConversionService调用转换方法,完全可以通过全局配置实现自动转换。
原因说明
@RestController的返回值默认走JSON序列化逻辑,由MappingJackson2HttpMessageConverter处理,这部分逻辑和请求参数绑定用的ConversionService格式化体系是相互独立的,所以你配置的DateFormatter不会在返回值序列化阶段被触发。
常用解决方案
根据你的业务场景可以选择对应方案:
场景1:接口返回JSON格式,需要所有Date类型统一序列化为yyyy-MM-dd格式
这是最常见的使用场景,直接全局配置Jackson的日期序列化规则即可:
@Configuration public class JacksonConfig { @Bean public ObjectMapper objectMapper() { ObjectMapper objectMapper = new ObjectMapper(); // 全局日期格式 objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")); // 按需设置时区,避免8小时差 objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8")); return objectMapper; } }
配置完成后,你原来的TestController不需要任何改动,返回的Date会自动转成你要的字符串格式。
场景2:接口直接返回纯文本日期字符串,不需要JSON包裹
如果你不需要JSON结构,就是要直接返回2021-09-04这种纯文本,可以自定义全局返回值处理器,复用你已经注册的DateFormatter:
@Configuration public class WebConfig implements WebMvcConfigurer { @Resource private FormattingConversionService conversionService; @Override public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) { handlers.add(new HandlerMethodReturnValueHandler() { @Override public boolean supportsReturnType(MethodParameter returnType) { return returnType.getParameterType() == Date.class; } @Override public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception { mavContainer.setRequestHandled(true); HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class); response.setContentType("text/plain;charset=utf-8"); // 直接用你配置的ConversionService转换,自动调用DateFormatter的print方法 String formatDate = conversionService.convert(returnValue, String.class); response.getWriter().write(formatDate); } }); } }
配置完成后,所有返回类型为Date的接口都会自动输出格式化后的日期字符串,不需要修改Controller代码。
关于你提到的手动调用方式
你写的手动注入FormattingConversionService调用convert的方式是可以正常运行的,但只适合单接口使用,如果多个接口都有相同需求,用上面的全局配置方案可避免重复代码。
内容的提问来源于stack exchange,提问作者andreren
相关产品推荐
相关产品推荐

