从 jar 运行时,Spring Boot 给出“TemplateInputException:解析模板时出错”

问题描述 投票:0回答:10

我有一个应用程序,在 IntelliJ 中或通过 gradle bootRun 启动时可以完美运行。

但是,如果我执行 gradle bootRepackage 然后尝试运行生成的 jar,我最终会得到:

2014-12-02 21:46:14.086 ERROR 9839 --- [nio-2014-exec-2] org.thymeleaf.TemplateEngine             : [THYMELEAF][http-nio-2014-exec-2] Exception processing template "/login": Error resolving template "/login", template might not exist or might not be accessible by any of the configured Template Resolvers
2014-12-02 21:46:14.087 ERROR 9839 --- [nio-2014-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.thymeleaf.exceptions.TemplateInputException: Error resolving template "/login", template might not exist or might not be accessible by any of the configured Template Resolvers] with root cause

org.thymeleaf.exceptions.TemplateInputException: Error resolving template "/login", template might not exist or might not be accessible by any of the configured Template Resolvers
    at org.thymeleaf.TemplateRepository.getTemplate(TemplateRepository.java:245)
    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.spring4.view.ThymeleafView.renderFragment(ThymeleafView.java:335)

我可以看到 jar 中包含 /templates/** 。内容对我来说看起来不错。

一个可能的(?)因素可能是我使用引用布局的 html 页面,因此:

layout:decorator="layouts/main"

我可以确认该文件在 jar 中。

/login 的定义如下:

@Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/login").setViewName("/login"); registry.addViewController("/").setViewName("/login"); }

我将 Spring Security 配置为:

@Configuration public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override public void configure(WebSecurity security) { security.ignoring().antMatchers("/assets/**"); } @Override protected void configure(HttpSecurity http) throws Exception { http .csrf().disable(); http .authorizeRequests() .antMatchers("/").permitAll() .anyRequest().authenticated(); http .formLogin() .loginPage("/login") .defaultSuccessUrl("/home") .failureUrl("/login?error") .permitAll() .and() .logout() .invalidateHttpSession(true) .logoutSuccessUrl("/login?logout") .permitAll(); } }

我认为这就是与这个问题相关的全部内容......

我已经看到了

https://github.com/spring-projects/spring-boot/issues/112Spring 的 Thymeleaf 视图的正确位置(以及其他)。尽管有这些资源,我还没有成功地使模板解析工作。

如有任何建议,我们将不胜感激。

Spring Boot 到目前为止已经走到了最后一步(接近最终部署),这真是令人烦恼。

spring spring-boot thymeleaf
10个回答
15
投票
我在默认配置下使用带有 thymeleaf 的 spring boot 时遇到了同样的问题。一切正常,直到我必须尝试 .jar

消息说: ... org.thymeleaf.exceptions.TemplateInputException:解析模板“/fragments/footer”时出错

我解决了玩 / 的问题,问题是他们不需要斜杠。

我改变了这个:

<footer class="footers" th:replace="/fragments/footer :: footer">

为此:

<footer class="footers" th:replace="fragments/footer :: footer">
    

8
投票
答案似乎就在这里:

https://github.com/spring-projects/spring-boot/issues/1744

简而言之:如果资源路径包含“//”,事情就会出错。

修复方法是修改application.yml:

spring: thymeleaf: prefix: classpath:/templates

(当然,修复方法与 .properties 文件类似)

连锁反应是所有对模板或任何内容的引用都需要在前面加上斜杠,如(Thymeleaf .html 文件):

layout:decorator="/layouts/main"

或(Groovy 控制器):

@RequestMapping(value = "/home", method = RequestMethod.GET) def home(Model model, Principal principal) { "/home/home" }

认为 Spring Boot 应该可以解决这个问题。紧急。这是非常糟糕的人体工程学设计,会严重爆炸,就在人们感觉接近最终部署的时候。


6
投票
好的,我找到了你要仔细看的地方。在您的控制器类中,当您在类上使用

@RequestMapping

 时,不要使用前导斜线(例如 
@RequestMapping("property")
)。在方法上,您需要一个前导斜杠(例如
@GetMapping("/list")
)并且返回值没有前导斜杠(例如
return "property/list";

示例片段

@Controller @RequestMapping("property") public class PropertyController { @NonNull PropertyService service; @GetMapping("/list") public String list() { return "property/list"; } }
    

2
投票
我在使用

spring-boot-starter-thymeleaf

 依赖项时遇到了问题

所以我使用了下面的依赖项,

<dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf</artifactId> <version>3.0.9.RELEASE</version> </dependency>
    

1
投票
如果上述解决方案对您(像我一样)不起作用,

我将控制器更改为 RestController。它解决了我的问题。

如果您使用 Angular 等前端应用程序与后端应用程序对话,则适用。


1
投票
对我来说,我的代码没有任何问题。我所做的就是在终端中运行

mvn clean

 命令,然后再次重新启动应用程序,一切正常。 


1
投票
这个问题与@Restcontroller有关,因为@RestController注释是@responseBody和@controller注释的混合

RestController 默认响应正文是 json 或字符串格式,添加任何字符串 html 名称都将其视为字符串,然后在默认 html 中显示字符串

将@restController更改为@controller即可工作


0
投票
spring.thymeleaf.prefix=类路径:/templates/

改变

@Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/login").setViewName("/login"); registry.addViewController("/").setViewName("/login"); }

@Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/login").setViewName("login"); registry.addViewController("/").setViewName("login"); }

视图名称应该是相对路径


0
投票
经过多次尝试,我找到了解决模板错误问题的方法。我不知道是否与新版本的 spring-boot 有关,但我的更改有效。

每个请求通过控制器而不是返回字符串“/login”,例如,我更改为创建一个对象ModelAndView:

@RequestMapping(value="/login", method=RequestMethod.GET) public ModelAndView login() { ModelAndView mv = new ModelAndView("login"); return mv; }

拥抱所有人。


0
投票
我的问题是我用大写 T 命名了模板目录。“Templates”

重命名为“模板”解决了问题

© www.soinside.com 2019 - 2024. All rights reserved.