我遵循了Thymeleaf教程“ Spring中带有Thymeleaf的Rich HTML电子邮件 ”中的内容,以使用Thymeleaf模板生成电子邮件。一切都很好,但是我无法访问在应用程序中其他地方使用的ApplicationContext bean。
更具体地说,在我的电子邮件模板中,我想要类似以下内容:
<span th:text="${@myBean.doSomething()}">
Run Code Online (Sandbox Code Playgroud)
其中“ myBean”是一个@Component。那有可能吗?我不是在寻找类似的解决方法
<span th:text="${myBean.doSomething()}">
Run Code Online (Sandbox Code Playgroud)
其中将bean作为变量添加到模板处理上下文中。
配置:
@Configuration
@EnableWebMvc
@EnableSpringDataWebSupport
public class MyWebConfig extends WebMvcConfigurerAdapter {
[....]
public ClassLoaderTemplateResolver emailTemplateResolver() {
ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
resolver.setPrefix("emailtemplates/");
resolver.setSuffix(".html");
resolver.setCharacterEncoding("UTF-8");
resolver.setTemplateMode("HTML5");
return resolver;
}
@Bean
public SpringTemplateEngine emailTemplateEngine() {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.addTemplateResolver(emailTemplateResolver());
engine.addDialect(new LayoutDialect()); // thymeleaf-layout-dialect
addSpringSecurityDialect(engine); // thymeleaf-SpringSecurity-dialect
return engine;
}
[....]
}
Run Code Online (Sandbox Code Playgroud)
电子邮件服务:
@Service
public class MyEmailService {
@Resource SpringTemplateEngine emailTemplateEngine;
[....]
public boolean sendHtmlEmail(...) {
final Context ctx = new Context(locale);
ctx.setVariable("someVariable", "someValue"); // Don't want to add myBean here
final String body = this.emailTemplateEngine.process("myTemplate", ctx);
[....]
Run Code Online (Sandbox Code Playgroud)
组件:
@Component
public class MyBean {
public String doSomething() {
return "Something done!";
}
}
Run Code Online (Sandbox Code Playgroud)
模板:
<span th:text="${@myBean.doSomething()}">
Run Code Online (Sandbox Code Playgroud)
错误:
EL1057E :(位置1):没有在上下文中注册任何bean解析器来解析对bean'myBean'的访问
我正在使用thymeleaf-2.1.4和spring-4.1.6
编辑:
请注意,我无法使用HttpServletRequest,因为我以@Async方法发送了大部分电子邮件,而该请求无法可靠地使用。这就是为什么我使用Context而不是WebContext的原因(尽管我不了解SpringWebContext-我想如果有人通过“ beans”变量使该类用于访问bean,那么使用@myBean表示法肯定是不可能的)。
Dar*_*idl 12
这很令人困惑,因为我们在这里有三种不同的上下文:
ApplicationContext不是WebApplicationContext。org.thymeleaf.context.Context您在其上设置/添加变量的 Thymeleaf 。org.springframework.expression.EvaluationContext,用于评估 SpEL 表达式。对于 Thymeleaf,这是ThymeleafEvaluationContext.如果您没有 Spring Web 上下文,您只需要添加ThymeleafEvaluationContext对应用程序上下文的引用作为 Thymeleaf 的变量Context:
例如(在 Kotlin 中)
@Service
class TemplateService(
private val templateEngine: TemplateEngine,
private val applicationContext: ApplicationContext
) {
fun processTemplate(locale: Locale, template: String, vararg variables: Pair<String, Any?>): String {
val context = Context(locale)
// Set the Thymeleaf evaluation context to allow access to Spring beans with @beanName in SpEL expressions
context.setVariable(ThymeleafEvaluationContext.THYMELEAF_EVALUATION_CONTEXT_CONTEXT_VARIABLE_NAME,
ThymeleafEvaluationContext(applicationContext, null))
// Set additional variables
variables.forEach { (key, value) -> context.setVariable(key, value) }
return templateEngine.process(template, context)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4900 次 |
| 最近记录: |