问题描述
项目在idea中可以正常访问,但是达成jar包后访问时候访问异常,并报错,部分异常栈如下:
org.thymeleaf.exceptions.TemplateInputException: Error resolving template [/views/login], template might not exist or might not be accessible by any of the configured Template Resolvers
at org.thymeleaf.engine.TemplateManager.resolveTemplate(TemplateManager.java:869) ~[thymeleaf-3.0.15.RELEASE.jar!/:3.0.15.RELEASE]
at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:607) ~[thymeleaf-3.0.15.RELEASE.jar!/:3.0.15.RELEASE]
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098) [thymeleaf-3.0.15.RELEASE.jar!/:3.0.15.RELEASE]
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1072) [thymeleaf-3.0.15.RELEASE.jar!/:3.0.15.RELEASE]
at org.thymeleaf.spring5.view.ThymeleafView.renderFragment(ThymeleafView.java:366) [thymeleaf-spring5-3.0.15.RELEASE.jar!/:3.0.15.RELEASE]
at org.thymeleaf.spring5.view.ThymeleafView.render(ThymeleafView.java:190) [thymeleaf-spring5-3.0.15.RELEASE.jar!/:3.0.15.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1406) [spring-webmvc-5.3.27.jar!/:5.3.27]
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1150) [spring-webmvc-5.3.27.jar!/:5.3.27]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) [spring-webmvc-5.3.27.jar!/:5.3.27]
可以看到是TemplateManager中resolveTemplate方法报错了
问题排查
因为只有打包后jar运行才报错,问了定位问题,本地启动jar时候开启一个远程debug端口5005,启动命令如下:
java -jar -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 target/pro-artifact-1.0.0.jar
IDEA添加Remote JVM Debug
定位
问题代码入口
问题节点
此处返回null导致无法加载页面,继续跟踪tempalteResource.exists方法,检查为什么返回false
exists方法检查
到此处,问题已经明了,path中多了一个斜杠。原因spring.thymleaf.prefix值为classpath:/templates/,但是配置页面以/views/开头,导致多一个/,这个在idea中没影响,但是部署jar执行的时候却无法识别。
thymleaf相关的yml配置
spring:
thymeleaf:
cache: false #关闭 Thymeleaf 的缓存开发过程中无需重启
encoding: UTF-8 #设置thymeleaf页面的编码
mode: HTML
#设置thymeleaf页面的后缀
suffix: .html
#设置thymeleaf页面的存储路径
prefix: classpath:/templates/
页面配置
@RequestMapping("/{pageName}")
public ModelAndView router(@PathVariable String pageName, HttpServletRequest request) {
ModelAndView modelAndView = new ModelAndView("/views/" + pageName);
modelAndView.addObject("ctx", request.getContextPath());
Subject subject = SecurityUtils.getSubject();
String loginUserName = String.valueOf(subject.getPrincipal());
User user = new User();
user.setUserName(loginUserName);
modelAndView.addObject("user", user);
return modelAndView;
}
解决方法
配置页面的时候检查前缀和页面配置,确保不要重复配置斜杠(/)。案例中讲prefix修改为classpath:/templates即可解决问题