关于GenericApplicationContext

时间:2015-08-22 15:47:25

标签: spring spring-boot thymeleaf

Spring-web,webmvc 4.1.6 Thymeleaf 2.1

我一直在为SpringBoot中的Thymeleaf配置manualy。 我想在ServletContextTemplateResolver中使用" classpath:"设置路径。字首。 我该怎么做才能解决这个问题?

@Bean
public ServletContextTemplateResolver templateResolver() {
    ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver();
    templateResolver.setPrefix("classpath:/templates/");
    templateResolver.setSuffix(".html");
    templateResolver.setTemplateMode("HTML5");        
    templateResolver.setCacheable(false);
    return templateResolver;
 }

但它不起作用。原因是下面的代码。 在org.springframework.context.support.GenericApplicationContext

@Override
public Resource getResource(String location) {
    if (this.resourceLoader != null) {
        return this.resourceLoader.getResource(location);    // with setting of template resolver
    }
    return super.getResource(location);    // without setting of template resolver
}

没有ServletContextTemplateResolver的任何设置, 调用GenericApplicationContext.getResource。

设置它 调用StandardRoot.getResourceAsStream。 但是这种方法并没有实现支持"类:"前缀。

成功获取资源

http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/support/GenericApplicationContext.html#getResource-java.lang.String-

"实现ClassPathResource"

@Override
public Resource getResource(String location) {
    Assert.notNull(location, "Location must not be null");
    if (location.startsWith("/")) {
        return getResourceByPath(location);
    }
    else if (location.startsWith(CLASSPATH_URL_PREFIX)) {
        return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());
    }
    else {
        try {
            // Try to parse the location as a URL...
            URL url = new URL(location);
            return new UrlResource(url);
        }
        catch (MalformedURLException ex) {
            // No URL -> resolve as resource path.
            return getResourceByPath(location);
        }
    }
}

getResource

失败

https://tomcat.apache.org/tomcat-8.0-doc/api/org/apache/catalina/webresources/StandardRoot.html#getResource(java.lang.String)

在这段代码中,前缀没有实现,所以我意识到我不能使用" class:" ServletContextTemplateResolver属性的前缀。

在org.apache.catalina.webresources.StandardRoot

@Override
public InputStream getResourceAsStream(String path) {

    if (path == null)
        return (null);

    if (!path.startsWith("/") && GET_RESOURCE_REQUIRE_SLASH)
        return null;

    WebResourceRoot resources = context.getResources();
    if (resources != null) {
         return resources.getResource(path).getInputStream();
    }

    return null;
}

2 个答案:

答案 0 :(得分:3)

为了将模板作为类路径项加载可选支持前缀路径,您应该使用ClassLoaderResourceResolver而不是ServletContextTemplateResolver (后者相对于您的Web应用程序上下文解析tempaltes,即在 / WEB-INF / 目录下):

@Bean
public ServletContextTemplateResolver templateResolver() {
    ITemplateResolver templateResolver = new ClassLoaderTemplateResolver();
    templateResolver.setPrefix("templates/");
    templateResolver.setSuffix(".html");
    templateResolver.setTemplateMode("HTML5");        
    templateResolver.setCacheable(false);
    return templateResolver;
 }

请注意,无需将 classpath: 前缀附加到模板路径前缀,因为类加载器解析器默认情况下会查找到类路径中。

您可能需要查看每个org.thymeleaf.templateresolver.TemplateResolver子类,它们提供了不同的加载资源的技术:

答案 1 :(得分:1)

对不起,我能够解决这个问题。

http://forum.thymeleaf.org/Loading-templates-from-external-source-td4025309.html

我改为使用了ClassLoaderTemplateResolver。

classLoaderTemplateResolver.setPrefix("templates/");