从jar运行时,Spring Boot提供“TemplateInputException:Error resolving template”

时间:2014-12-02 12:07:09

标签: spring spring-boot thymeleaf

我有一个在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/112Proper location of Thymeleaf views for Spring(等等)。尽管有这些资源,我还没有成功地使模板解析工作。

感谢任何建议。

到目前为止,使用Spring Boot还没遇到最后一道障碍(接近最终部署)是无理取闹的。

9 个答案:

答案 0 :(得分:7)

我在默认配置下使用带百里香的弹簧靴有同样的问题。一切顺利,直到我必须尝试.jar

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

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

我改变了这个:

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

为此:

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

答案 1 :(得分:4)

答案似乎在这里:https://github.com/spring-projects/spring-boot/issues/1744

简而言之:如果资源路径包含&#39; //&#39;,事情就会出错。

修复方法是修改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"
}

认为春季启动应该解决这个问题。急。这真是糟糕的人体工程学,在人们感觉就像接近最终部署的时候,它会严重爆炸。

答案 2 :(得分:4)

好的,我发现你必须仔细看看。在Controller类中,当您在类上使用@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";
    }
}

答案 3 :(得分:1)

如果上述解决方案对您不起作用,例如我,

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

这是,如果您正在使用Angular之类的前端应用程序与您的后端应用程序对话。

答案 4 :(得分:0)

spring.thymeleaf.prefix =类路径:/模板/

变化

@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");
}

视图名称应为“相对路径”

答案 5 :(得分:0)

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

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

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

拥抱所有人。

答案 6 :(得分:0)

使用spring-boot-starter-thymeleaf依赖项

时遇到了问题

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

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

答案 7 :(得分:0)

对我来说,我的代码没有错。我所做的只是在终端中运行mvn clean命令,然后再次重新启动应用程序,它运行正常。

答案 8 :(得分:0)

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

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

把@restController 改成@controller 就可以了