非Web环境下如何在ThymeLeaf中为类型注册自定义格式化器?
解决SpringBoot非Web应用中Thymeleaf自定义格式化器不生效的问题
你的问题核心在于:非Web应用下,WebMvcConfigurer的配置不会被Spring触发,而且Thymeleaf的TemplateEngine没有关联到自定义的ConversionService,导致变量只能用默认的toString()输出。下面是具体的解决步骤:
1. 实现自定义Formatter
因为Printer只负责格式化输出,而Formatter同时继承了Printer和Parser(如果不需要解析字符串到对象,可以在parse方法中抛出异常),更适合注册到ConversionService:
DateFormatter实现
public class DateFormatter implements Formatter<Date> { @Override public String print(Date date, Locale locale) { return new SimpleDateFormat("yyyy-MM-dd").format(date); } @Override public Date parse(String text, Locale locale) throws ParseException { // 非Web应用通常不需要解析字符串到Date,直接抛出不支持异常即可 throw new UnsupportedOperationException("不支持Date类型的解析操作"); } }
DurationFormatter实现
public class DurationFormatter implements Formatter<Duration> { @Override public String print(Duration duration, Locale locale) { // 自定义Duration的格式化规则,示例转为"XX小时XX分钟" return String.format("%d小时%d分钟", duration.toHours(), duration.toMinutesPart()); } @Override public Duration parse(String text, Locale locale) throws ParseException { throw new UnsupportedOperationException("不支持Duration类型的解析操作"); } }
2. 配置ConversionService并绑定到Thymeleaf
在非Web应用中,需要手动创建ConversionService并注册自定义Formatter,然后将其关联到Thymeleaf的SpringTemplateEngine:
@Configuration public class ThymeleafConfig { // 创建自定义ConversionService,注册Formatter @Bean public ConversionService conversionService() { DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService(); conversionService.addFormatter(new DateFormatter()); conversionService.addFormatter(new DurationFormatter()); return conversionService; } // 配置Thymeleaf模板引擎,关键是设置ConversionService @Bean public TemplateEngine templateEngine(ITemplateResolver templateResolver, ConversionService conversionService) { SpringTemplateEngine templateEngine = new SpringTemplateEngine(); templateEngine.setTemplateResolver(templateResolver); // 绑定ConversionService,让Thymeleaf使用自定义格式化规则 templateEngine.setConversionService(conversionService); return templateEngine; } // 配置模板解析器,指向classpath下的templates目录 @Bean public ITemplateResolver templateResolver() { ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver(); templateResolver.setPrefix("templates/"); templateResolver.setSuffix(".html"); templateResolver.setTemplateMode(TemplateMode.HTML); templateResolver.setCharacterEncoding("UTF-8"); return templateResolver; } }
3. 验证使用
在模板中直接使用变量即可,Thymeleaf会自动通过ConversionService进行格式化:
<p>报告名称:<span th:text="${reportName}"></span></p> <p>日期:<span th:text="${someDate}"></span></p> <p>时长:<span th:text="${someDuration}"></span></p>
为什么原来的方法无效?
WebMvcConfigurer是专为Web MVC场景设计的,非Web应用中Spring不会自动调用其addFormatters方法;- 你之前没有将自定义的格式化器关联到Thymeleaf的
TemplateEngine,导致Thymeleaf无法识别这些规则,只能用默认的toString()输出变量。
内容的提问来源于stack exchange,提问作者fml2
相关产品推荐
相关产品推荐

