如何在Thymeleaf TEXT模板中调用静态方法并绕过Restricted模式限制
原生Thymeleaf 3.0.12+ 调用自定义静态方法的可行方案
你遇到的报错是Thymeleaf 3.0.12版本默认开启的OGNL表达式受限模式导致的,该模式默认禁止静态类访问、对象实例化等操作避免注入风险,以下是3种可在最新版本实现需求的方案:
方案1:直接关闭OGNL受限模式
适用场景:完全掌控所有模板内容、无安全风险的场景,是改动最小的解决方案。
配置代码示例:
import org.thymeleaf.TemplateEngine; import org.thymeleaf.standard.StandardDialect; import org.thymeleaf.standard.expression.OGNLVariableExpressionEvaluator; import org.thymeleaf.standard.expression.StandardOGNLExpressionParser; // 初始化模板引擎 TemplateEngine templateEngine = new TemplateEngine(); // 创建关闭了受限模式的OGNL表达式解析器 StandardOGNLExpressionParser parser = new StandardOGNLExpressionParser(false); OGNLVariableExpressionEvaluator evaluator = new OGNLVariableExpressionEvaluator(parser); // 替换标准方言的表达式求值器 StandardDialect standardDialect = new StandardDialect(); standardDialect.setVariableExpressionEvaluator(evaluator); templateEngine.addDialect(standardDialect);
配置完成后,你之前尝试的@类全路径@静态方法和T(类全路径).静态方法两种写法都可以正常使用。
方案2:注册自定义全局表达式工具类(官方推荐)
该方案符合Thymeleaf的设计规范,不需要关闭安全限制,和内置的#numbers、#dates等工具类使用方式完全一致,适合长期使用的自定义功能。
实现步骤
- 编写自定义数字格式化工具类
public class CustomNumberUtils { // 你的自定义格式化静态方法 public static String formatCustom(Number number, String pattern) { // 自定义格式化逻辑 return result; } }
- 实现表达式对象方言,注册为全局实用对象
import org.thymeleaf.context.IExpressionContext; import org.thymeleaf.dialect.AbstractDialect; import org.thymeleaf.expression.IExpressionObjectFactory; import java.util.Collections; import java.util.Set; public class CustomUtilsDialect extends AbstractDialect implements IExpressionObjectDialect { public CustomUtilsDialect() { super("CustomUtilsDialect"); } @Override public IExpressionObjectFactory getExpressionObjectFactory() { return new IExpressionObjectFactory() { // 定义工具类的调用前缀,这里用#customNumbers @Override public Set<String> getAllExpressionObjectNames() { return Collections.singleton("customNumbers"); } @Override public Object buildObject(IExpressionContext context, String expressionObjectName) { return new CustomNumberUtils(); } @Override public boolean isCacheable(String expressionObjectName) { return true; } }; } }
- 把自定义方言加入模板引擎
templateEngine.addDialect(new CustomUtilsDialect());
配置完成后可直接在TEXT模板中调用:
自定义格式结果:[(${#customNumbers.formatCustom(orderAmount, '0.00')})]
方案3:全局自动注入静态类到模板上下文
如果不想修改方言和表达式配置,可以封装通用渲染工具类,自动注入工具类到上下文,无需每次手动添加变量:
import org.thymeleaf.context.Context; import java.util.Map; public class TemplateRenderUtils { private static final TemplateEngine templateEngine; static { templateEngine = new TemplateEngine(); // 其他模板引擎初始化配置 } public static String render(String templateName, Map<String, Object> businessVariables) { Context context = new Context(); // 全局自动注入自定义工具类 context.setVariable("NumberUtils", CustomNumberUtils.class); // 放入业务变量 context.setVariables(businessVariables); return templateEngine.process(templateName, context); } }
模板中调用方式:
自定义格式结果:[(${NumberUtils.formatCustom(orderAmount, '0.00')})]
内容的提问来源于stack exchange,提问作者Ultranium
相关产品推荐
相关产品推荐

