【问题标题】:Thymeleaf Rich HTML email errorThymeleaf Rich HTML 电子邮件错误
【发布时间】:2015-10-19 07:24:43
【问题描述】:

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

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

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

问题,这么多人,我想发送丰富的 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("/mail/"); 并重新组织 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>

【问题讨论】:

    标签: java eclipse spring html-email thymeleaf


    【解决方案1】:

    我几乎可以肯定问题来自此配置:

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

    /WEB-INF/mailTemplates 在战争中不在类路径中。相反,将您的 mailTemplates 文件夹放在 src/resources 中。然后它会被放在 /WEB-INF/classes/ 中,你应该可以通过这个配置访问它们:

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

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

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

    【讨论】:

    • 这个解决方案解决了我的问题。但我还有一个问题。为什么 webTemplateResolver 采用位于下一行的模板: webResolver.setPrefix("/WEB-INF/templates/");正确吗?我认为它会以同样的方式工作。我应该改变这个配置来避免市长问题吗?谢谢!
    • 这是因为它是一个 ServletContextTemplateResolver。实际上,您可以将电子邮件模板的 ClassLoaderTemplateResolver 替换为 ServletContextTemplateResolver,并保留您的“/WEB-INF/mailTemplates/”电子邮件模板位置。
    • 明白!我会保持这种方式(2 个解析器),除非只有一个有一些改进,但两种方式都是一样的,对吧?
    • 是的,它们只是模板所在位置的 2 个不同配置选项
    猜你喜欢
    • 2017-05-02
    • 2017-08-03
    • 1970-01-01
    • 2016-10-02
    • 2013-11-03
    • 2019-04-17
    • 2019-06-07
    • 2021-05-10
    • 1970-01-01
    相关资源
    最近更新 更多