我在为电子邮件定义ClassLoaderTemplateResolver
和为网络视图定义一个ServletContextTemplateResolver
时遇到问题。尝试发送电子邮件时出现以下错误:
HTTP Status 500 - 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]
我的WebMvcConfig看起来像这样:
private static final String VIEWS_PATH = "/WEB-INF/views/";
private static final String MAIL_PATH = "mail/";
@Bean
public ServletContextTemplateResolver templateResolver() {
final ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
resolver.setPrefix(VIEWS_PATH);
resolver.setSuffix(".html");
resolver.setTemplateMode("HTML5");
resolver.setCharacterEncoding("UTF-8");
resolver.setOrder(2);
resolver.setCacheable(false);
return resolver;
}
@Bean
public ClassLoaderTemplateResolver emailTemplateResolver() {
final ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
resolver.setPrefix(MAIL_PATH);
resolver.setSuffix(".html");
resolver.setTemplateMode("HTML5");
resolver.setCharacterEncoding("UTF-8");
resolver.setOrder(1);
return resolver;
}
@Bean
public SpringTemplateEngine templateEngine() {
final SpringTemplateEngine engine = new SpringTemplateEngine();
final Set<TemplateResolver> templateResolvers = new HashSet<TemplateResolver>();
templateResolvers.add(templateResolver());
templateResolvers.add(emailTemplateResolver());
engine.setTemplateResolvers(templateResolvers);
engine.addDialect(new SpringSocialDialect());
engine.addDialect(new SpringSecurityDialect());
return engine;
}
我的EmailService
喜欢这样:
@Service
public class EmailService {
@Autowired
private JavaMailSender mailSender;
@Autowired
private TemplateEngine templateEngine;
/*
* Send HTML mail with inline image
*/
public void sendEmailToBookSeller(
final ContactBookSellerForm form,
final Locale locale) throws MessagingException {
boolean multipart = true;
boolean isHtml = true;
// Prepare the evaluation context
final Context ctx = new Context(locale);
ctx.setVariable("message", form.getMessage());
ctx.setVariable("bookTitle", form.getBookTitle());
ctx.setVariable("email", form.getToEmail());
ctx.setVariable("logo", "logo");
ctx.setVariable("logoOnlyText", "logoOnlyText");
// Prepare message
final MimeMessage mimeMessage = mailSender.createMimeMessage();
final MimeMessageHelper message = new MimeMessageHelper(mimeMessage, multipart, "UTF-8");
message.setSubject("Regarding your book on Mimswell - " + form.getBookTitle());
message.setFrom(form.getFromEmail());
message.setTo(form.getToEmail());
// Create the HTML body using Thymeleaf
final String htmlContent = templateEngine.process("email-buy-book.html", ctx);
message.setText(htmlContent, isHtml);
message.addInline("logo", new ClassPathResource("WEB-INF/views/mail/logo130130red.png"), "image/png");
message.addInline("logoOnlyText", new ClassPathResource("WEB-INF/views/mail/logo_only_text.png"), "image/png");
// Send mail
this.mailSender.send(mimeMessage);
}
}
错误在以下行中出现:
final String htmlContent = templateEngine.process("email-buy-book.html", ctx);
使用ServletContextResourceResolver
而不是我的其他解析器。我希望它使用ClassLoaderTemplateResolver
,因为它可以处理普通Context
对象,而不必使用WebContext
。但是,我可以尝试使用WebContext
,因为它实现了IWebContext
并且只使用一个解析器。但是我需要HttpServletRequest
,HttpServletResponse
和ServletContext
作为参数,这似乎很麻烦。
我的结构:
我的代码中有什么想法错了吗?
答案 0 :(得分:1)
我放弃了这个并转而采用WebContext
方法,即使我每次发送内容时都需要请求,响应和servletcontext。我就这样做了:
<强> 1。获取servlet上下文:
@Autowired
ServletContext servletContext;
<强> 2。获取请求和响应作为sendmail方法的参数:
HttpServletRequest request,
HttpServletResponse response
第3。改为创建WebContext:
final WebContext ctx = new WebContext(request, response, servletContext, locale);
从现在开始工作。
答案 1 :(得分:1)
由于您(正确地)将ClassLoaderTemplateResolver设置为优先于ServletContextTemplateResolver,因此Thymeleaf尝试使用正确的顺序,但无法使用前者解析视图,然后尝试后者。
我相信问题在于您设置的前缀和后缀参数与传递给templateEngine.process方法的视图名称相结合。 Thymeleaf将通过连接后缀+ viewname +后缀来构建您的视图名称,结果为&#34; mail / email-buy-book.html.html&#34; 。
尝试仅传递&#34; email-buy-book&#34; ,看看它是否解决了问题。
答案 2 :(得分:0)
由于您正在使用ClassLoaderTemplateResolver,因此Spring将使用该前缀并将其附加到WEB-INF / classes。因此,要检查的是Maven(或您正在使用的任何构建工具)是否将html文件复制到WEB-INF / classes / mail / email-buy-book.html。如果没有,请尝试手动复制并试一试。看看你的截图,我没有看到&#34; mail&#34; &#34;类&#34;下的文件夹所以这可能是个问题。
此外,只需通过&#34;电子邮件购买书&#34;并且在@grid提到时省略了扩展名。
final String htmlContent = templateEngine.process("email-buy-book", ctx);
我使用XML配置而不是Java配置,但我不明白为什么这对你来说很重要。