Thymeleaf Rich HTML 电子邮件错误

Thymeleaf Rich HTML email error

首先,我已经阅读了有关 thymeleaf 电子邮件渲染的所有问题,我的意思是,原始教程:

http://www.thymeleaf.org/doc/articles/springmail.html

以及其他已解决的关于此的 Whosebug 问题,问题是我无法找到合适的解决方案,这开始很烦人......所以,请问,你能帮我解决这个问题吗?

这个问题,和很多人一样,我想发送丰富的 HTML 电子邮件,这是我的 Thymeleaf 配置:

@Configuration
public class ThymeleafConfig {

    @Bean
    public ClassLoaderTemplateResolver emailTemplateResolver(){
        ClassLoaderTemplateResolver emailResolver = new ClassLoaderTemplateResolver();
        emailResolver.setPrefix("/WEB-INF/mailTemplates/");
        emailResolver.setSuffix(".html");
        emailResolver.setTemplateMode("HTML5");
        emailResolver.setOrder(1);
        return emailResolver;
    }

    @Bean
    public ServletContextTemplateResolver webTemplateResolver() {
        ServletContextTemplateResolver webResolver = new ServletContextTemplateResolver();
        webResolver.setPrefix("/WEB-INF/templates/");
        webResolver.setSuffix(".html");
        webResolver.setTemplateMode("HTML5");
        webResolver.setOrder(2);
        return webResolver;
    }

    @Bean
    public SpringTemplateEngine templateEngine() {
        SpringTemplateEngine engine = new SpringTemplateEngine();
        engine.addTemplateResolver(emailTemplateResolver());
        engine.addTemplateResolver(webTemplateResolver());
        engine.addDialect(new SpringSecurityDialect());
        return engine;
    }

    @Bean
    public ThymeleafViewResolver thymeleafViewResolver() {
        ThymeleafViewResolver resolver = new ThymeleafViewResolver();
        resolver.setTemplateEngine(templateEngine());
        resolver.setOrder(1);
        return resolver;
    }
}

在emailResolver.setPrefix("/WEB-INF/mailTemplates/");我试着把原来的例子配置换成一行,比如 emailResolver.setPrefix("/邮件/"); 并重组 eclipse 项目中的文件。现在是这样

发送邮件的方法是这样的:

public void sendRegistrationEmail(String contextPath, Locale locale, User user) throws MessagingException{
        String token = UUID.randomUUID().toString();
        userService.createVerificationToken(user, token);

        String recipientAddress = user.getEmail();
        String subject = "Register";
        String confirmationUrl = contextPath + "/regitrationConfirm.html?token=" + token;

        String imageResourceName= "/images/myLogo.jpg";
        final Context ctx = new Context(locale);
        ctx.setVariable("name", user.getShownUsername());
        ctx.setVariable("subscriptionDate", new Date());
        ctx.setVariable("logo", imageResourceName);
        ctx.setVariable("name", user.getShownUsername());
        ctx.setVariable("loginName", user.getUsername());
        ctx.setVariable("email", user.getEmail());
        ctx.setVariable("link", confirmationUrl);

        final String htmlContent = templateEngine.process("registrationTemplate", ctx);

        final MimeMessage mimeMessage = this.mailSender.createMimeMessage();
        final MimeMessageHelper message = new MimeMessageHelper(mimeMessage);
        message.setFrom("<" + env.getProperty("email.username") + ">");
        message.setTo("<" + recipientAddress + ">");
        message.setSubject(subject);
        message.setText(htmlContent,true);

        mailSender.send(mimeMessage);
    }

当然,还有错误 Tomcat 指出 Servlet 上下文无法呈现此模板。

我已经调试了 thymelead 代码,当它必须呈现模板时,我检查了它如何尝试使用 ClassLoaderTemplateResolver 呈现邮件:

它只需在日志中写入这条消息:

logger.trace("[THYMELEAF][{}] Template \"{}\" could not be resolved as resource \"{}\" with resource resolver \"{}\"", new Object[] {TemplateEngine.threadIndex(), templateName, resourceName, resourceResolver.getName()});

使用此参数:

resourceName = /WEB-INF/mailTemplates/registrationTemplate.html
templateName = registrationTemplate
resourceResolver.getName() = org.thymeleaf.resourceresolver.ClassLoaderResourceResolver

我很确定这个错误是在某些配置或类似的东西中的一个小问题,我现在不知道在哪里搜索它...

当它不使用 ClassLoader 渲染模板时异常运行,然后它尝试使用第二个承租人模板,Servlet 模板,它因这个众所周知的错误而崩溃:

Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateProcessingException: Resource resolution by ServletContext with org.thymeleaf.resourceresolver.ServletContextResourceResolver can only be performed when context implements org.thymeleaf.context.IWebContext [current context: org.thymeleaf.context.Context]] con causa raíz
org.thymeleaf.exceptions.TemplateProcessingException: Resource resolution by ServletContext with org.thymeleaf.resourceresolver.ServletContextResourceResolver can only be performed when context implements org.thymeleaf.context.IWebContext [current context: org.thymeleaf.context.Context]

有什么想法吗?

我读过这个方法: Using multiple template resolvers with Spring 3.2 and Thymeleaf 2.1.3 for emails

但是让它与像 Thymeleaf 示例一样的配置一起工作会很好,避免发送请求等

提前致谢!

编辑:

要添加更多信息,这里是电子邮件模板:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
  <head>
    <title th:remove="all">Registration Template</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  </head>
  <body>
    <p th:text="#{email.registration.greeting(${name})}">
      Hello, Username!
    </p>
    <p>
      Registering on <span th:text="${#dates.format(subscriptionDate)}">Date</span>.
    </p>
    <p>Your data:</p>
    <ul th:remove="all-but-first">
      <li th:text="#{email.registration.loginname(${loginName})}">Login: username</li>
      <li th:text="#{email.registration.shownusername(${shownUserName})}">show name: UserName</li>
      <li th:text="#{email.registration.email(${email})}">email: user@mail.com</li>
    </ul>
    <p>
      Register link:
    </p>
    <p th:text="${link}"></p>
    <p>
      Thanks!
    </p>
    <p>
      <img src="sample.png" th:src="'cid:' + ${logo}" />
    </p>
  </body>
</html>

我几乎可以肯定问题出在这个配置上:

ClassLoaderTemplateResolver emailResolver = new ClassLoaderTemplateResolver();
emailResolver.setPrefix("/WEB-INF/mailTemplates/");
当您在 war 中时,

/WEB-INF/mailTemplates 不在类路径中。相反,将您的 mailTemplates 文件夹放在 src/resources 中。然后它将被放入 /WEB-INF/classes/ 中的 war,您应该可以使用此配置访问它们:

ClassLoaderTemplateResolver emailResolver = new ClassLoaderTemplateResolver();
emailResolver.setPrefix("/mailTemplates/");

编辑: 另一种解决方案是也对电子邮件模板使用 ServletContextTemplateResolver :

ServletContextTemplateResolver emailResolver = new ServletContextTemplateResolver();
emailResolver.setPrefix("/WEB-INF/mailTemplates/");