Spring和Thymeleaf - 无法初始化:未设置模板解析器

时间:2017-11-05 19:41:24

标签: java spring spring-boot thymeleaf

我目前正在开发一个Spring Boot应用程序。在尝试创建电子邮件服务时遇到错误。

application.properties:

spring.thymeleaf.prefix=classpath:/static/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=LEGACYHTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
spring.thymeleaf.cache=true

在访问应用程序网址时,从主控制器解析index.html。但是电子邮件模板没有得到解决。

MainController:

  @RequestMapping("/")
        public String home() {
            return "index";
        }

EmailService:

JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        Locale locale = new Locale.Builder().setLanguage("en").setRegion("US").build();     
         // Prepare the evaluation context
        final Context ctx = new Context(locale);        
         ctx.setVariable("saveComplaints", saveComplaintEntity);

         // Prepare message using a Spring helper
          MimeMessage mimeMessage = mailSender.createMimeMessage();
          MimeMessageHelper message =
             new MimeMessageHelper(mimeMessage, true, "UTF-8"); // true = multipart
         message.setSubject("Example HTML email with inline image");
         message.setFrom("****@gmail.com");
         message.setTo("*****@gmail.com");

         // Create the HTML body using Thymeleaf
          String htmlContent = templateEngine.process("email", ctx);
          message.setText(htmlContent, true); // true = isHtml


         // Send mail
         mailSender.send(mimeMessage);

“email”模板名称是指与index.html位于同一位置的email.html文件(classpath:/ static /)

错误:

nested exception is org.thymeleaf.exceptions.ConfigurationException: Cannot initialize: no template resolvers have been set] with root cause:
org.thymeleaf.exceptions.ConfigurationException: Cannot initialize: no template resolvers have been set

编辑:

smtp配置:

spring.mail.host=smtp.gmail.com
spring.mail.username= *****@gmail.com   
spring.mail.password= *****
spring.mail.port=587
spring.mail.defaultEncoding=UTF-8
spring.mail.properties.mail.smtp.starttls.enable=true

提供邮件时出错:

java.net.SocketException: Permission denied: connect; message exceptions (1) are:
Failed message 1: com.sun.mail.util.MailConnectException: Couldn't connect to host, port: localhost, 25; timeout -1;
nested exception is:
java.net.SocketException: Permission denied: connect] with root cause

完成错误跟踪:

 2017-11-06 03:48:57.827 ERROR 38292 --- [nio-9999-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.mail.MailSendException: Mail server connection failed; nested exception is com.sun.mail.util.MailConnectException: Couldn't connect to host, port: localhost, 25; timeout -1;
  nested exception is:
    java.net.ConnectException: Connection refused: connect. Failed messages: com.sun.mail.util.MailConnectException: Couldn't connect to host, port: localhost, 25; timeout -1;
  nested exception is:
    java.net.ConnectException: Connection refused: connect; message exceptions (1) are:
Failed message 1: com.sun.mail.util.MailConnectException: Couldn't connect to host, port: localhost, 25; timeout -1;
  nested exception is:
    java.net.ConnectException: Connection refused: connect] with root cause

java.net.ConnectException: Connection refused: connect
    at java.net.DualStackPlainSocketImpl.connect0(Native Method) ~[na:1.7.0_80]
    at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source) ~[na:1.7.0_80]
    at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source) ~[na:1.7.0_80]
    at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source) ~[na:1.7.0_80]
    at java.net.AbstractPlainSocketImpl.connect(Unknown Source) ~[na:1.7.0_80]
    at java.net.PlainSocketImpl.connect(Unknown Source) ~[na:1.7.0_80]
    at java.net.SocksSocketImpl.connect(Unknown Source) ~[na:1.7.0_80]
    at java.net.Socket.connect(Unknown Source) ~[na:1.7.0_80]
    at java.net.Socket.connect(Unknown Source) ~[na:1.7.0_80]
    at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:331) ~[javax.mail-1.5.6.jar:1.5.6]
    at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:238) ~[javax.mail-1.5.6.jar:1.5.6]
    at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:2084) ~[javax.mail-1.5.6.jar:1.5.6]
    at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:712) ~[javax.mail-1.5.6.jar:1.5.6]
    at javax.mail.Service.connect(Service.java:366) ~[javax.mail-1.5.6.jar:1.5.6]
    at org.springframework.mail.javamail.JavaMailSenderImpl.connectTransport(JavaMailSenderImpl.java:501) ~[spring-context-support-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:421) ~[spring-context-support-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:345) ~[spring-context-support-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:340) ~[spring-context-support-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at com.demo.email.service.EmailService.sendMail(EmailService.java:45) ~[classes/:na]
    at com.demo.email.controller.MailController.sendMail(MailController.java:32) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_80]
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.7.0_80]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.7.0_80]
    at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.7.0_80]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133) ~[spring-web-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97) ~[spring-webmvc-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) ~[spring-webmvc-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) ~[spring-webmvc-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967) ~[spring-webmvc-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) ~[spring-webmvc-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) ~[spring-webmvc-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) ~[spring-webmvc-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.20.jar:8.5.20]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:108) ~[spring-web-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) ~[spring-web-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.11.RELEASE.jar:4.3.11.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) ~[tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478) [tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80) [tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799) [tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1457) [tomcat-embed-core-8.5.20.jar:8.5.20]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.20.jar:8.5.20]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na:1.7.0_80]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [na:1.7.0_80]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.20.jar:8.5.20]
    at java.lang.Thread.run(Unknown Source) [na:1.7.0_80]

解决方案:

@AutoWired 
TemplateEngine templateEngine 

创建了新的SpringTemplateEngine对象。

@Autowired
JavaMailSenderImpl mailSender

创建新的JavaMailSenderImpl对象。

3 个答案:

答案 0 :(得分:1)

而不是在创建新模板引擎的SpringTemplateEngine templateEngine = new SpringTemplateEngine();,而是必须autowire使用@AutoWired TemplateEngine templateEngine

由Spring Boot创建的模板引擎

对于来自Spring Boot应用程序的电子邮件,我会推荐this库,这使得发送电子邮件非常简单!!

答案 1 :(得分:1)

在我的情况下,我尝试了@ MohamedSanaulla的建议并将以下内容添加到我的Spring @Configuration课程中:

@Autowired
public void configureSpringTemplateEngine(SpringTemplateEngine springTemplateEngine) {
    springTemplateEngine.addDialect(new LayoutDialect());
}

然后我开始获得关于LayoutDialect两次声明的重复方言相关异常。所以我只是完全删除了它(因此,既没有尝试实例化新的SpringTemplateEngine,也没有尝试通过向它添加LayoutDialect来配置我提供给我的那个,并且它被罚款。

答案 2 :(得分:0)

为了避免这个问题,我做了这样的事情。

public PdfCreationServiceImpl(SpringTemplateEngine templateEngine) { this.templateEngine = templateEngine; ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver(); templateResolver.setPrefix("templates/"); templateResolver.setSuffix(".html"); templateResolver.setTemplateMode(TemplateMode.HTML); templateEngine.setTemplateResolver(templateResolver); this.templateEngine = templateEngine; }