You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 10:51:03