2015-03-11 16 views
5

Sto usando Thymeleaf SpringTemplateEngine per creare una e-mail HTML sulla mia applicazione Spring. Quando stavo usando Spring MVC tutto era perfetto. Ora con Spring Boot la classe non riesce a trovare il mio modello .html. Penso che il problema sia con ServletContext che non restituisce il percorso corretto, ma non riesco a capire come risolverlo. Quindi dovrei usare un altro contesto per elaborare il modello? Quale?Come utilizzare SpringTemplateEngine quando si utilizza Spring Boot

Questo è il mio MailService che funziona per Spring MVC puro.

import java.io.File; 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.io.UnsupportedEncodingException; 
import java.util.HashSet; 
import java.util.Locale; 
import java.util.Set; 

import javax.mail.MessagingException; 
import javax.mail.internet.InternetAddress; 
import javax.mail.internet.MimeMessage; 
import javax.servlet.ServletContext; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

import org.apache.poi.util.IOUtils; 
import org.springframework.core.io.ByteArrayResource; 
import org.springframework.core.io.InputStreamSource; 
import org.springframework.mail.javamail.JavaMailSenderImpl; 
import org.springframework.mail.javamail.MimeMessageHelper; 
import org.springframework.stereotype.Service; 
import org.thymeleaf.context.WebContext; 
import org.thymeleaf.spring3.SpringTemplateEngine; 
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver; 
import org.thymeleaf.templateresolver.ITemplateResolver; 

@Service 
public class MailService { 

    private JavaMailSenderImpl mailSender; 

    private SpringTemplateEngine templateEngine; 

    public MailService() { 
     mailSender = new JavaMailSenderImpl(); 
     //mailSender config 

     templateEngine = new SpringTemplateEngine(); 
     Set<ITemplateResolver> templatesResolvers = new HashSet<ITemplateResolver>(); 

     ClassLoaderTemplateResolver emailTemplateResolver = new ClassLoaderTemplateResolver(); 
     emailTemplateResolver.setPrefix("mail/"); 
     emailTemplateResolver.setTemplateMode("HTML5"); 
     emailTemplateResolver.setCharacterEncoding("UTF-8"); 
     emailTemplateResolver.setOrder(1); 
     templatesResolvers.add(emailTemplateResolver); 

     ServletContextTemplateResolver webTemplateResolver = new ServletContextTemplateResolver(); 
     webTemplateResolver.setPrefix("/mail/"); 
     webTemplateResolver.setTemplateMode("HTML5"); 
     webTemplateResolver.setCharacterEncoding("UTF-8"); 
     webTemplateResolver.setOrder(2); 
     templatesResolvers.add(webTemplateResolver); 

     templateEngine.setTemplateResolvers(templatesResolvers); 
    } 

    public void sendReport(String nome, String email, String obra, 
      long medicao, HttpServletRequest request, 
      HttpServletResponse response, ServletContext context, Locale locale) 
      throws MessagingException { 

     String subject = "Novo relatório"; 

     final WebContext ctx = new WebContext(request, response, context, 
       locale); 
     ctx.setVariable("nome", nome); 
     ctx.setVariable("obra", obra); 
     ctx.setVariable("data", DataUtils.getInstance().getDataString(medicao)); 
     ctx.setVariable("logo", "logo.jpg"); 

     final MimeMessage mimeMessage = this.mailSender.createMimeMessage(); 
     final MimeMessageHelper message = new MimeMessageHelper(mimeMessage, 
       true, "UTF-8"); 
     message.setSubject(subject); 
     try { 
      message.setFrom(new InternetAddress(mailSender.getUsername(), 
        "Sistema")); 
     } catch (UnsupportedEncodingException e) { 
     } 
     message.setTo(email); 

     final String htmlContent = this.templateEngine.process(
       "email-relatorio.html", ctx); 
     message.setText(htmlContent, true); 

     try { 
      File file = new File(context.getRealPath("app/img/logo-pro.jpg")); 
      InputStreamSource imageSource = new ByteArrayResource(
        IOUtils.toByteArray(new FileInputStream(file))); 
      message.addInline("logo.jpg", imageSource, "image/jpg"); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     this.mailSender.send(mimeMessage); 
    } 
} 

L'errore:

org.thymeleaf.exceptions.TemplateInputException: Error resolving template "email-relatorio.html", template might not exist or might not be accessible by any of the configured Template Resolvers 
    at org.thymeleaf.TemplateRepository.getTemplate(TemplateRepository.java:246) 
    at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1104) 
    at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1060) 
    at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1011) 
    at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:924) 
    at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:898) 

risposta

15

Si utilizza Primavera di avvio poi lasciare Primavera avvio fare il lavoro pesante, che lo fa già. Rimuovere il costruttore e semplicemente @Autowire il JavaMailSender e SpringTemplateEngine.

Aggiungere la configurazione della posta allo application.properties.

spring.mail.host=your-mail-server 
spring.mail.port= 
spring.mail.username 
spring.mail.password 

aggiungere la configurazione foglia di timo alle application.properties

# THYMELEAF (ThymeleafAutoConfiguration) 
spring.thymeleaf.check-template-location=true 
spring.thymeleaf.prefix=classpath:/templates/ 
spring.thymeleaf.excluded-view-names= # comma-separated list of view names that should be excluded from resolution 
spring.thymeleaf.view-names= # comma-separated list of view names that can be resolved 
spring.thymeleaf.suffix=.html 
spring.thymeleaf.mode=HTML5 
spring.thymeleaf.encoding=UTF-8 
spring.thymeleaf.content-type=text/html # ;charset=<encoding> is added 
spring.thymeleaf.cache=true # set to false for hot refresh 

Se avete fatto che cambia la classe

@Service 
public class MailService { 

    @Autowired 
    private JavaMailSender mailSender; 

    @Autowired 
    private SpringTemplateEngine templateEngine; 

    @Value("${spring.mail.username}") 
    private String username; 

    public void enviarRelatorio(String nome, String email, String obra,long medicao, Locale locale) throws MessagingException { 

     String subject = "Novo relatório"; 

     final Context ctx = new Context(locale); 
     ctx.setVariable("nome", nome); 
     ctx.setVariable("obra", obra); 
     ctx.setVariable("data", DataUtils.getInstance().getDataString(medicao)); 
     ctx.setVariable("logo", "logo.jpg"); 

     final MimeMessage mimeMessage = this.mailSender.createMimeMessage(); 
     final MimeMessageHelper message = new MimeMessageHelper(mimeMessage,true, "UTF-8"); 
     message.setSubject(subject); 
     message.setTo(email); 

     try { 
      message.setFrom(new InternetAddress(username, "Sistema")); 
     } catch (UnsupportedEncodingException e) { 
     } 

     final String htmlContent = this.templateEngine.process("email-relatorio", ctx); 
     message.setText(htmlContent, true); 

     try { 
      message.addInline("logo.jpg", new FileSystemResource("imgs/logo-pro.jpg"), "image/jpg"); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     this.mailSender.send(mimeMessage); 
    } 
} 
+0

Hi! Sto usando application.properties ora. Tuttavia, il prefisso "classpath:/templates /" genera lo stesso errore e se si imposta su "templates /" ThymeleafAutoConfiguration genera "Impossibile trovare il percorso del modello: templates/(per favore aggiungi alcuni template o controlla la configurazione di Thymeleaf)". Il mio file è in src/main/resources/templates. Cosa mi manca? – rcorreia

+2

Lascia perdere. Il problema era perché stavo passando il nome completo del file, ma c'era un suffisso. Cambiare "email-relatorio.html" in "email-relatorio" e un cast da JavaMailSender a JavaMailSenderImpl quando si utilizza getUsername. Grazie! – rcorreia

+0

Non si dovrebbe eseguire il cast o usare 'getUsename' per iniettare la proprietà con una proprietà basata su' @ Value'. Vedi il codice modificato. Il cast potrebbe essere problematico a causa del fatto che AOP è disponibile e come tale non è possibile eseguire il cast su 'JavaMailSenderImpl' ma solo sull'interfaccia. Accanto a ciò dovresti programmare su interfacce e non su classi concrete ... Inoltre 'src/main/resources/templates' è il percorso predefinito in modo da non doverlo configurare. –