Search code examples
spring-bootjakarta-mailhtml-emailfreemarker

How to send email with Freemarker template in Spring Boot app?


I am trying to send email with Freemarker template.

Code:

public String geContentFromTemplate(Map<String, Object> model) throws IOException, TemplateException {
        StringWriter stringWriter = new StringWriter();
        fmConfiguration.getTemplate("email-template.ftlh").process(model, stringWriter);
        return stringWriter.getBuffer().toString();
}

public void sendEmailWithTemplate(String to, String subject, User user) {
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        try {

            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);

            mimeMessageHelper.setSubject(subject);
            mimeMessageHelper.setFrom(emailFrom);
            mimeMessageHelper.setTo(to);
            Map<String, Object> model = new HashMap<>();
            model.put("firstName", user.getFirstName());
            model.put("lastName", user.getLastName());
            String content = geContentFromTemplate(model);
            mimeMessageHelper.setText(content, true);

            mailSender.send(mimeMessageHelper.getMimeMessage());
        } catch (MessagingException | IOException | TemplateException e) {
            e.printStackTrace();
        }
    }

Freemarker Bean:

 @Bean
    public FreeMarkerConfigurationFactoryBean getFreeMarkerConfiguration() {
        FreeMarkerConfigurationFactoryBean fmConfigFactoryBean = new FreeMarkerConfigurationFactoryBean();
        fmConfigFactoryBean.setTemplateLoaderPath("classpath:templates/email-template.ftlh");
        return fmConfigFactoryBean;
    }

My template is located in Spring Boot application: resources/templates/email-template.ftlh

I receive this exception: freemarker.template.TemplateNotFoundException: Template not found for name "email-template.ftlh". The name was interpreted by this TemplateLoader: org.springframework.ui.freemarker.SpringTemplateLoader@33cceeb3.


Solution

  • I fixed that by changing @Bean. I removed previous one and created another:

      @Bean
        public FreeMarkerConfigurer freeMarkerConfigurer(){
            freemarker.template.Configuration configuration = new freemarker.template.Configuration(freemarker.template.Configuration.VERSION_2_3_19);
            TemplateLoader templateLoader = new ClassTemplateLoader(this.getClass(), "/templates/");
            configuration.setTemplateLoader(templateLoader);
            FreeMarkerConfigurer freeMarkerConfigurer = new FreeMarkerConfigurer();
            freeMarkerConfigurer.setConfiguration(configuration);
            return freeMarkerConfigurer;
        }
    

    Also template loading implemented like that:

                Template template = freeMarkerConfigurer.getConfiguration().getTemplate("email-template.ftlh");
                String htmlBody = FreeMarkerTemplateUtils.processTemplateIntoString(template, model);