我们正在使用视图层中的 Thymeleaf 模板库和提供 SPEL 支持的 Thymeleaf SpringTemplateEngine 开发一个 Spring MVC (v4) Web 应用程序。
当我们在模板中引用类型时(例如,为了访问静态实用程序方法或枚举),我们必须包含完全限定名称,因为 Spring StandardEvaluationContext StandardTypeLocator 默认只知道 java.lang 包。我可以在 Spring API 中看到,我们需要使用 registerImport(String prefix) 方法将自己的包添加到类型定位器中,但我不知道如何获取模板中使用的默认评估上下文能够做到这一点。
我想通过替换这种东西来整理我们的 Thymeleaf HTML 模板:
与:
我尝试将一个 EvaluationContext 自动装配到一个控制器中,看看我是否可以得到它,但 Spring 告诉我没有找到符合条件的 bean。任何建议表示赞赏!
我正在使用基于 JAVA 的 spring 配置。所以在 spring 安全配置类中(必须有一个 @EnableGlobalMethodSecurity(prePostEnabled = true) 注释),我正在注入一个自定义 MethodSecurityExpressionHandler bean:
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public MethodSecurityExpressionHandler methodSecurityExpressionHandler() { DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler() { @Override public StandardEvaluationContext createEvaluationContextInternal(final Authentication auth, final MethodInvocation mi) { StandardEvaluationContext evaluationContext = super.createEvaluationContextInternal(auth, mi); //Register custom package paths, since StandardTypeLocator is only aware of"java.lang" //So there will be no need to provide a fully qualified path ((StandardTypeLocator) evaluationContext.getTypeLocator()).registerImport("desired.path"); return evaluationContext; } }; expressionHandler.setPermissionEvaluator(new ExpressionAccessPermissionEvaluator()); //register some custom PermissionEvaluator if any return expressionHandler; } } |
谢谢
我不确定这是否能解决您的问题,但 ThymeleafViewResolver 类具有 addStaticVariable 方法,可在处理视图之前将变量添加到上下文中。
我做了一个小测试:
2 3 4 5 6 7 | ThymeleafViewResolver thymeleafViewResolver; @PostConstruct public void postConstruct() { thymeleafViewResolver.addStaticVariable("myUtil", new StringUtils()); } |
使用 StringUtils 如下:
2 3 4 5 | public static String print() { return"Printed"; } } |
还有观点:
2 | Test |
两者都工作得很好。如果您的方法不是静态的,后者也可以工作。
希望对你有帮助。
我设法通过package EngineContextFactory 类来做到这一点,所以我在我的 Thymeleaf 配置类中如下所示:
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | public SpringTemplateEngine springTemplateEngine(SpringResourceTemplateResolver templateResolver, IDialect springSecurityDialect) { SpringTemplateEngine templateEngine = new SpringTemplateEngine(); templateEngine.setTemplateResolver(templateResolver); templateEngine.setEngineContextFactory(engineContextFactory()); templateEngine.addDialect(springSecurityDialect); return templateEngine; } private IEngineContextFactory engineContextFactory() { return new EngineContextFactoryWrapper() // packages to register .registerImport("java.util") .registerImport("java.math") .registerImport("com.mainsys.fhome.gui.util"); } public static class EngineContextFactoryWrapper implements IEngineContextFactory { private final IEngineContextFactory delegate; private final List<String> typeLocatorPrefixes; public EngineContextFactoryWrapper() { super(); delegate = new StandardEngineContextFactory(); typeLocatorPrefixes = new ArrayList<String>(); } @Override public IEngineContext createEngineContext(IEngineConfiguration configuration, TemplateData templateData, Map<String, Object> templateResolutionAttributes, IContext context) { IEngineContext engineCtx = delegate.createEngineContext(configuration, templateData, templateResolutionAttributes, context); EvaluationContext evaluationContext; if (engineCtx.containsVariable(ThymeleafEvaluationContext.THYMELEAF_EVALUATION_CONTEXT_CONTEXT_VARIABLE_NAME)) { evaluationContext = (EvaluationContext) engineCtx.getVariable(ThymeleafEvaluationContext.THYMELEAF_EVALUATION_CONTEXT_CONTEXT_VARIABLE_NAME); } else { evaluationContext = new ThymeleafEvaluationContextWrapper(new StandardEvaluationContext()); } for (String prefix : typeLocatorPrefixes) { ((StandardTypeLocator) evaluationContext.getTypeLocator()).registerImport(prefix); } return engineCtx; } public EngineContextFactoryWrapper registerImport(String prefix) { typeLocatorPrefixes.add(prefix); return this; } } |