Thymeleaf Spring 5 在 web-inf 中找不到 html 模板

问题描述 投票:0回答:1

我想使用 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/模板/通知)读取而不是从类路径资源(资源/模板/通知)读取。

java spring spring-boot thymeleaf
1个回答
0
投票

我知道这是一个老问题,但我发现自己在这里遇到了类似的问题,经过几个小时的探索后终于解决了。以下是对我有用的最新版本,此处标记为: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
中的某些东西最初对你来说可能缺失了?

希望这对其他人有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.