在基于Web的Scopes of Spring中使用Thymeleaf处理HTML文件,并将处理后的模板存储为String

我正在尝试使用thymeleaf呈现HTML文件,并将结果HTML内容保存在web-based scopes of Spring String变量中web-based scopes of Spring以便我以后可以使用它来发送电子邮件或将内容转换为pdf。 我已经完成了本网站给出的实现,但它给了我一些我无法弄清楚的错误。 我正在使用春季靴子1.5.12.RELEASE与thymeleaf 3.0.9 n thymeleaf方言2.2.2。 以下是我的实施。 请帮忙。

 import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.Context; import org.thymeleaf.templatemode.TemplateMode; import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver; @Controller public class jataController { @GetMapping(value = "/manual-thym") @ResponseBody public void justSample() { Context context = new Context(); String filename = "templates/view/failure"; String html = renderHtml(filename, context); System.out.println("template\n" + html); } private String renderHtml(String filename, Context context) { ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver(); templateResolver.setSuffix(".html"); templateResolver.setTemplateMode(TemplateMode.HTML); templateResolver.setCacheable(false); templateResolver.setOrder(1); templateResolver.setCharacterEncoding("UTF-8"); TemplateEngine templateEngine = new TemplateEngine(); templateEngine.setTemplateResolver(templateResolver); String html = templateEngine.process(filename, context); return html; } } 

而StackTrace:

 2018-04-19 12:26:43.742 ERROR 6375 --- [nio-9000-exec-9] oaccC[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: ognl/PropertyAccessor] with root cause java.lang.ClassNotFoundException: ognl.PropertyAccessor at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_162] at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_162] at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338) ~[na:1.8.0_162] at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_162] at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.8.0_162] at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~[na:1.8.0_162] at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[na:1.8.0_162] at java.net.URLClassLoader.defineClass(URLClassLoader.java:467) ~[na:1.8.0_162] at java.net.URLClassLoader.access$100(URLClassLoader.java:73) ~[na:1.8.0_162] at java.net.URLClassLoader$1.run(URLClassLoader.java:368) ~[na:1.8.0_162] at java.net.URLClassLoader$1.run(URLClassLoader.java:362) ~[na:1.8.0_162] at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_162] at java.net.URLClassLoader.findClass(URLClassLoader.java:361) ~[na:1.8.0_162] at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_162] at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338) ~[na:1.8.0_162] at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_162] at org.thymeleaf.standard.expression.OGNLVariableExpressionEvaluator.(OGNLVariableExpressionEvaluator.java:83) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE] at org.thymeleaf.standard.StandardDialect.getVariableExpressionEvaluator(StandardDialect.java:179) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE] at org.thymeleaf.standard.StandardDialect.getExecutionAttributes(StandardDialect.java:393) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE] at org.thymeleaf.DialectSetConfiguration.build(DialectSetConfiguration.java:263) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE] at org.thymeleaf.EngineConfiguration.(EngineConfiguration.java:123) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE] at org.thymeleaf.TemplateEngine.initialize(TemplateEngine.java:336) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE] at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1079) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE] at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1059) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE] at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1048) ~[thymeleaf-3.0.9.RELEASE.jar:3.0.9.RELEASE] at com.siqes.flight.controller.jataController.renderHtml(jataController.java:37) ~[classes/:na] at com.siqes.flight.controller.jataController.justSample(jataController.java:19) ~[classes/:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_162] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_162] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_162] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_162] at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-4.3.16.RELEASE.jar:4.3.16.RELEASE] at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133) ~[spring-web-4.3.16.RELEASE.jar:4.3.16.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97) ~[spring-webmvc-4.3.16.RELEASE.jar:4.3.16.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) ~[spring-webmvc-4.3.16.RELEASE.jar:4.3.16.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) ~[spring-webmvc-4.3.16.RELEASE.jar:4.3.16.RELEASE] at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.3.16.RELEASE.jar:4.3.16.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967) ~[spring-webmvc-4.3.16.RELEASE.jar:4.3.16.RELEASE] at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) ~[spring-webmvc-4.3.16.RELEASE.jar:4.3.16.RELEASE] at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.3.16.RELEASE.jar:4.3.16.RELEASE] at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) ~[spring-webmvc-4.3.16.RELEASE.jar:4.3.16.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:635) ~[tomcat-embed-core-8.5.29.jar:8.5.29] at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) ~[spring-webmvc-4.3.16.RELEASE.jar:4.3.16.RELEASE] at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[tomcat-embed-core-8.5.29.jar:8.5.29] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-8.5.29.jar:8.5.29] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.29.jar:8.5.29] at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.29.jar:8.5.29] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.29.jar:8.5.29] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.29.jar:8.5.29] at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55) ~[spring-boot-1.5.12.RELEASE.jar:1.5.12.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.16.RELEASE.jar:4.3.16.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.29.jar:8.5.29] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.29.jar:8.5.29] at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:111) ~[spring-boot-actuator-1.5.12.RELEASE.jar:1.5.12.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.16.RELEASE.jar:4.3.16.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.29.jar:8.5.29] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.29.jar:8.5.29] at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.3.16.RELEASE.jar:4.3.16.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.16.RELEASE.jar:4.3.16.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.29.jar:8.5.29] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.29.jar:8.5.29] at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) ~[spring-web-4.3.16.RELEASE.jar:4.3.16.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.16.RELEASE.jar:4.3.16.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.29.jar:8.5.29] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.29.jar:8.5.29] at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) ~[spring-web-4.3.16.RELEASE.jar:4.3.16.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.16.RELEASE.jar:4.3.16.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.29.jar:8.5.29] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.29.jar:8.5.29] at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.16.RELEASE.jar:4.3.16.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.16.RELEASE.jar:4.3.16.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.29.jar:8.5.29] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.29.jar:8.5.29] at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:106) ~[spring-boot-actuator-1.5.12.RELEASE.jar:1.5.12.RELEASE] at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.16.RELEASE.jar:4.3.16.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-8.5.29.jar:8.5.29] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-8.5.29.jar:8.5.29] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) ~[tomcat-embed-core-8.5.29.jar:8.5.29] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.29.jar:8.5.29] at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:613) [tomcat-embed-core-8.5.29.jar:8.5.29] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.29.jar:8.5.29] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.29.jar:8.5.29] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.29.jar:8.5.29] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.29.jar:8.5.29] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803) [tomcat-embed-core-8.5.29.jar:8.5.29] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.29.jar:8.5.29] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790) [tomcat-embed-core-8.5.29.jar:8.5.29] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459) [tomcat-embed-core-8.5.29.jar:8.5.29] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.29.jar:8.5.29] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_162] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_162] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.29.jar:8.5.29] at java.lang.Thread.run(Thread.java:748) [na:1.8.0_162] 

请参阅下面的更新

配置Thymeleaf时,您应该定义模板引擎和模板解析器,否则在使用自动assembly默认值时。 如果每次创建实例都不是一个好习惯。 这里有一个示例配置:

 @Configuration @EnableWebMvc public class ThymeleafConfiguration { @Bean public SpringTemplateEngine templateEngine() { SpringTemplateEngine templateEngine = new SpringTemplateEngine(); templateEngine.setTemplateResolver(thymeleafTemplateResolver()); return templateEngine; } @Bean public SpringResourceTemplateResolver thymeleafTemplateResolver() { SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver(); templateResolver.setPrefix("/WEB-INF/views/"); templateResolver.setSuffix(".html"); templateResolver.setTemplateMode("HTML5"); return templateResolver; } } 

然后,如果你想以编程方式进行实验,你可以自动assembly它们,但是使用百万美元提供html页面的常用流程也是定义视图解析器:

 @Bean public ThymeleafViewResolver thymeleafViewResolver() { ThymeleafViewResolver viewResolver = new ThymeleafViewResolver(); viewResolver.setTemplateEngine(templateEngine()); return viewResolver; } 

有了这些,您可以将控制器编写为:

 @Controller public class MyController { @RequestMapping(value = "/test", method = RequestMethod.GET) public String test() { return "yourTemplateName"; } } 

可以使用模型属性将参数传递给模板。

更新31/07/2018

遗憾的是,我没有时间完成工作概念certificate,但我认为下面的代码足以显​​示流程。 如果你运行它并调用localhost:8080/test你应该能够在控制台中看到输出html。 pdf生成可以作为视图解析器添加和/或以编程方式调用,在此示例中使用xhtmlrenderer ; 我没有时间来完成它所以我评论了它,但你可以明白:服务通过自动assembly模板引擎提供html和pdf生成。

在此处输入图像描述

的pom.xml

   4.0.0 com.github.paizo html2pdf 0.0.1-SNAPSHOT jar html2pdf Demo project for Spring Boot  org.springframework.boot spring-boot-starter-parent 2.0.3.RELEASE     UTF-8 UTF-8 1.8    org.springframework.boot spring-boot-starter-thymeleaf   org.springframework.boot spring-boot-starter-web   org.xhtmlrenderer flying-saucer-pdf 9.1.14   org.springframework.boot spring-boot-starter-test test      org.springframework.boot spring-boot-maven-plugin     

ThymeleafConfiguration.java

 @Configuration public class ThymeleafConfiguration { @Bean public SpringTemplateEngine templateEngine() { SpringTemplateEngine templateEngine = new SpringTemplateEngine(); templateEngine.setTemplateResolver(thymeleafTemplateResolver()); return templateEngine; } @Bean public ClassLoaderTemplateResolver thymeleafTemplateResolver() { ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver(); templateResolver.setPrefix("templates/"); templateResolver.setSuffix(".html"); templateResolver.setTemplateMode("HTML5"); return templateResolver; } } 

HelloWorldController.java

 @Controller public class HelloWorldController { @Autowired private Html2PdfService pdfService; @GetMapping(path = "/test") public String hello() { Map parameters = new HashMap(); parameters.put("name", "Borat"); System.out.println(pdfService.template2Html("test", parameters)); return "test"; } // @ResponseBody // @GetMapping // public ResponseEntity helloPdf() { // Map parameters = new HashMap(); // parameters.put("name", "Borat"); // pdfService.template2Pdf("test", parameters); // String filePath = "PATH_HERE"; // InputStream inputStream = new FileInputStream(new File(filePath)); // InputStreamResource inputStreamResource = new InputStreamResource(inputStream); // HttpHeaders headers = new HttpHeaders(); // headers.setContentLength(); // return new ResponseEntity(inputStreamResource, headers, HttpStatus.OK); // } } 

Html2PdfService.java

 @Service public class Html2PdfService { @Autowired private TemplateEngine templateEngine; public OutputStream template2Pdf(String templateName, Map parameters) { // OutputStream outputStream = new BufferedOutputStream(); // IOUtils.copy() // // Context ctx = new Context(); // String processedHtml = templateEngine.process(templateName, ctx); // ITextRenderer renderer = new ITextRenderer(); // renderer.setDocumentFromString(processedHtml); // renderer.layout(); // renderer.createPDF(os, false); // renderer.finishPDF(); return null; } public String template2Html(String templateName, Map parameters) { Context ctx = new Context(); ctx.setVariable("name", "pippo"); String processedHtml = templateEngine.process(templateName, ctx); return processedHtml; } } 

Html2pdfApplication.java

 @SpringBootApplication public class Html2pdfApplication { public static void main(String[] args) { SpringApplication.run(Html2pdfApplication.class, args); } } 

作为附注,如果您计划动态生成pdf并将其作为控制器中的响应提供,我建议使用流而不是字节数组或临时文件。

我正在使用类似的Springboot和Thymeleaf版本,这样的东西在一些项目上对我有用:

 import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.Context; @Component public class EmailProcessor { private TemplateEngine htmlTemplateEngine; @Autowired public EmailProcessor(TemplateEngine templateEngine) { this.htmlTemplateEngine = templateEngine; } public String process(User user) { final Context ctx = new Context(); if (user != null) { ctx.setVariable("user", user); } return htmlTemplateEngine.process("emails/template", ctx); } } 

电子邮件模板只是一个常规的Thymeleaf模板,位于:

resouces /模板/电子邮件/ template.html

如果TemplateEnginesingleton bean中自动assembly,那么下面提到的代码就完美了。

 @Controller public class jataController { @Autowired private TemplateEngine templateEngine; @GetMapping(value = "/manual-thym") @ResponseBody public void justSample() { Context context = new Context(); String filename = "templates/view/generated-ticket.html"; String html = renderHtml(filename, context); System.out.println("template\n" + html); } private String renderHtml(String filename, Context context) { ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver(); templateResolver.setSuffix(".html"); templateResolver.setTemplateMode(TemplateMode.HTML); templateResolver.setCacheable(false); templateResolver.setOrder(1); templateResolver.setCharacterEncoding("UTF-8"); templateEngine.setTemplateResolver(templateResolver); String html = templateEngine.process(filename, context); return html; } } 

但是如果TemplateEnginerequest范围bean类型上自动assembly,它会产生exception,而thymeleaf会产生内存泄漏。 所以最后有很多热门和尝试,我得到了一个有效的解决方案,感谢@Paizo。 它可能包含一些不好的做法,但这是它的工作原理:

 @Controller @Configuration @EnableWebMvc @ApplicationScope public class MyThymeleafConfig { @GetMapping("/view-template") @ResponseBody public void viewTemplates() { Context context = new Context(); context.setVariable("mydata", "this is it"); String html = templateEngine().process("templates/view-to-process.html", context); System.out.println(html); } /* configuration for thymeleaf and template processing */ @Bean public SpringTemplateEngine templateEngine() { SpringTemplateEngine templateEngine = new SpringTemplateEngine(); templateEngine.setTemplateResolver(thymeleafTemplateResolver()); return templateEngine; } @Bean public SpringResourceTemplateResolver thymeleafTemplateResolver() { SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver(); templateResolver.setPrefix("classpath:"); templateResolver.setSuffix(".html"); templateResolver.setCacheable(false); templateResolver.setTemplateMode(TemplateMode.HTML); return templateResolver; } @Bean public ThymeleafViewResolver thymeleafViewResolver() { ThymeleafViewResolver viewResolver = new ThymeleafViewResolver(); viewResolver.setTemplateEngine(templateEngine()); return viewResolver; } } 

并提供我们需要定义另一个bean的静态资源,如下所示:

 @Configuration @EnableWebMvc public class StaticResourceConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry .addResourceHandler("/**") .addResourceLocations("/static/", "classpath:static/"); } } 

在任何论坛上都找不到此解决方案。 但是我会要求任何Spring开发人员为上面的代码提供更好的实现