【问题标题】:Spring 4 + Thymeleaf 3 templates not found when placed outside WEB-INF folder放置在 WEB-INF 文件夹之外时找不到 Spring 4 + Thymeleaf 3 模板
【发布时间】:2017-07-02 03:16:36
【问题描述】:

我的 spring-boot 项目中有以下文件夹结构。

<prject>
- main
--java
--resources
---static (css, js, images etc)
---templates (html files)

我得到与模板文件相关的文件未找到异常,如下所示。

java.io.FileNotFoundException: Could not open ServletContext resource [/templates/user/form.html]

我的POM文件如下

<packaging>jar</packaging>
...
<dependencies>
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf</artifactId>
            <version>3.0.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring4</artifactId>
            <version>3.0.3.RELEASE</version>
        </dependency>
...
</dependencies>

而且,我的配置类如下:

@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter implements ApplicationContextAware {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**")
                .addResourceLocations("classpath:/static/");
    }

    private ApplicationContext applicationContext;

    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }


    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.favorPathExtension(true).
                favorParameter(false).
                ignoreAcceptHeader(true).
                useJaf(false).
                defaultContentType(MediaType.APPLICATION_JSON);
    }

    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        for (HttpMessageConverter<?> converter : converters) {
            if (converter instanceof MappingJackson2HttpMessageConverter) {
                MappingJackson2HttpMessageConverter jsonMessageConverter = (MappingJackson2HttpMessageConverter) converter;
                ObjectMapper objectMapper = jsonMessageConverter.getObjectMapper();
                objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
                break;
            }
        }
    }

    @Bean
    public ObjectMapper objectMapper()
    {
        ObjectMapper mapper = new ObjectMapper();
        mapper.findAndRegisterModules();
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        mapper.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false);
        return mapper;
    }


    @Bean
    public ITemplateResolver templateResolver() {
        SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
        templateResolver.setApplicationContext(applicationContext);
        templateResolver.setPrefix("/templates/");
        templateResolver.setSuffix(".html");
        templateResolver.setTemplateMode(TemplateMode.HTML);

        return templateResolver;
    }

    @Bean
    public TemplateEngine templateEngine() {
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.setEnableSpringELCompiler(true);
        templateEngine.setTemplateResolver(templateResolver());
        templateEngine.setTemplateEngineMessageSource(messageSource());
        templateEngine.addDialect(new LayoutDialect());
        return templateEngine;
    }


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

    @Bean
    public ResourceBundleMessageSource messageSource() {
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        messageSource.setBasename("messages");
        return messageSource;
    }

}

当模板放置在 webapp/WEB-INF 中并且模板解析器前缀设置为它时,它可以工作。

当使用 spring-boot-starter-thymeleaf 体面而不是我在这里使用的两个百里香叶依赖项并且配置从 MvcConfig 文件中完全删除时,它也可以工作。

你能告诉我一种使用相同文件夹结构和依赖项的方法吗?

【问题讨论】:

  • 试试 templateResolver.setPrefix("/resources/templates/") ?
  • @MinjunYu 你的简单修复就像一个魅力。

标签: spring-mvc spring-boot thymeleaf


【解决方案1】:

我在前缀中添加了classpath:,它对我有用:emailTemplateResolver.setPrefix("classpath:/templates/");

【讨论】:

    【解决方案2】:

    正如@Minjun Yu 所说,我可以在我的配置中添加templateResolver.setPrefix("/resources/templates/") 来修复它。

    问候

    【讨论】:

      猜你喜欢
      • 2020-08-27
      • 1970-01-01
      • 2018-02-18
      • 1970-01-01
      • 2016-09-16
      • 1970-01-01
      • 2015-10-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多