我想使用 thymeleaf 发送电子邮件作为电子邮件内容,但似乎在 WEB-INF/templates/notifications 中找不到 html 模板。
我在 Spring Boot 上使用 thymeleaf spring 5。
Spring boot (2.0.2.RELEASE)
和 Thymeleaf-spring5 (3.0.11.RELEASE)
以下是我的配置/更改:
POM
...
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.11.RELEASE</version>
</dependency>
...
通知模板配置
@Configuration
public class NotificationTemplateConfiguration {
@Bean
@Qualifier(value = "myTemplateEngine")
public SpringTemplateEngine springTemplateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.addTemplateResolver(myTemplateResolver());
return templateEngine;
}
@Bean
public SpringResourceTemplateResolver myTemplateResolver(){
SpringResourceTemplateResolver myTemplateResolver = new SpringResourceTemplateResolver();
myTemplateResolver.setPrefix("WEB-INF/templates/notifications/");
myTemplateResolver.setSuffix(".html");
myTemplateResolver.setTemplateMode(TemplateMode.HTML);
myTemplateResolver.setCharacterEncoding(StandardCharsets.UTF_8.name());
// I tried adding these lines but still it does not work
// myTemplateResolver.setOrder(0);
// myTemplateResolver.setCheckExistence(true);
return myTemplateResolver;
}
}
电子邮件服务
@Component
public class EmailService {
...
@Autowired
@Qualifier(value = "myTemplateEngine")
private SpringTemplateEngine m_myTemplateEngine;
...
private String buildContent() {
final Context context = new Context();
context.setVariable("recvName", getRecvName());
context.setVariable("inquiry", getInquiry());
context.setVariable("logoImageUrl", getLogoImageUrl());
// This is causing the error as it cannot find `WEB-INF/templates/notifications/inquiry-notification.html`, but this file really exists
return m_templateEngine.process("inquiry-notification", context);
}
public void sendEmail() throws MessagingException {
MimeMessage message = m_javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true, ConstantUtil.CHARACTER_ENCODING);
String content = buildContent();
helper.setFrom(getFromEmail());
helper.setReplyTo(getNoReplyEmail());
helper.setText(content, true);
helper.setSubject(getSubject());
helper.setTo(getRecipientEmail());
m_javaMailSender.send(message);
}
}
现在,我在
buildContent()
: 上遇到错误
Caused by: java.io.FileNotFoundException: class path resource [WEB-INF/templates/notifications/inquiry-notification.html] cannot be opened because it does not exist
at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:180)
at org.thymeleaf.spring5.templateresource.SpringResourceTemplateResource.reader(SpringResourceTemplateResource.java:103)
at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:223)
... 16 common frames omitted
问题
文件
WEB-INF/templates/notifications/inquiry-notification.html
已存在,并且即使我检查war文件,它也位于WEB-INF/templates/notifications
内部。问题出在 m_templateEngine.process("inquiry-notification", context)
上,因为即使存在也找不到 inquiry-notification
。如果我注释掉这一点并仅返回一个硬编码字符串(仅用于测试)...它将发送电子邮件而不会出现任何错误。
这个
WEB-INF/templates/notifications/inquiry-notification.html
确实存在,但我不知道为什么它找不到它。
知道为什么在 WEB-INF 中找不到该文件以及如何修复它吗?
更新:
如果我将前缀更改为:
myTemplateResolver.setPrefix("类路径:/templates/notifications/");
并将文件夹从
WEB-INF/templates/notifications/
移至 resources/templates/notifications
。
一切正常,但我想使用
WEB-INF/templates/notifications/
而不是 resources/templates/notifications
。
正如@Ralph评论的那样,可以在异常中看到它是从类路径资源而不是上下文资源读取。
我现在的问题是如何让它从上下文资源(WEB-INF/模板/通知)读取而不是从类路径资源(资源/模板/通知)读取。
我知道这是一个老问题,但我发现自己在这里遇到了类似的问题,经过几个小时的探索后终于解决了。以下是对我有用的最新版本,此处标记为:https://www.baeldung.com/thymeleaf-in-spring-mvc
Pom.xml
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.1.2.RELEASE</version>
</dependency>
尽管 baeldung 网站指出
ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver();
如果没有 servletContext
的论证就无法工作,但以下内容对我有用:
WebMVCConfig.java
@Bean
public SpringResourceTemplateResolver templateResolver() {
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setPrefix("/WEB-INF/views/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML5");
return templateResolver;
}
@Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
templateEngine.setTemplateEngineMessageSource(messageSource());
return templateEngine;
}
@Bean
public ThymeleafViewResolver thymeleafViewResolver(){
final ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
viewResolver.setViewNames(new String[] {"thyme/*"});
viewResolver.setExcludedViewNames(new String[] {"*.jsp"});
viewResolver.setCharacterEncoding("UTF-8");
return viewResolver;
}
最后是控制器:
@RestController("home")
@RequestMapping(value = "debug", method = RequestMethod.GET)
public ModelAndView debugConsole() {
User currentUser = getUserAndCheckAdmin();
ModelAndView mav = new ModelAndView("thyme/debug");
return mav;
}
也可以用作:
@Controller('home')
@GetMapping("/debug")
public String debugConsole(Model model) {
return "thyme/debug";
}
现在我可以在
WEB-INF/views/thyme/
阅读 Thymeleaf 文件。也许我的WebMVCConfig.java
中的某些东西最初对你来说可能缺失了?
希望这对其他人有帮助。