【问题标题】:Thymeleaf template is not able to find related JS, CSS and i18n filesThymeleaf 模板找不到相关的 JS、CSS 和 i18n 文件
【发布时间】:2021-01-23 09:19:45
【问题描述】:

我正在开发 Spring Boot 2 + thymeleaf Web 应用程序。我想渲染一个模板,它是来自 jar 文件的静态资源。我收到 js、CSS 和 message.properties 文件的 404 错误,而模板正在浏览器上呈现,但相关的 js、css 没有。为了从 jar 文件中渲染模板,我配置了 ClassLoaderTemplateResolver,如下所述:

  @Bean
public ClassLoaderTemplateResolver secondaryTemplateResolver() throws IOException {
    
    ClassLoaderTemplateResolver secondaryTemplateResolver = new 
     ClassLoaderTemplateResolver(getCustomeClassLoader());
    secondaryTemplateResolver.setPrefix("mytemplates/");
    secondaryTemplateResolver.setSuffix(".html");
    secondaryTemplateResolver.setTemplateMode(TemplateMode.HTML);
    secondaryTemplateResolver.setCharacterEncoding("UTF-8");
    secondaryTemplateResolver.setOrder(2);
    secondaryTemplateResolver.setCheckExistence(true);
    
    return secondaryTemplateResolver;
}

getCustomClassloader() 将返回加载我的 test.jar 文件的 URLclassloader 实例(当前类的类加载器作为父类加载器传递)。这个 jar 文件包含我所有的模板(html 文件)+ 静态文件(JS、CSS、属性)。下面是jar文件的结构:

test.jar
 |
 |- mytemplates -> myhtml.html
 |- static
      |- js ->my.js
      |- css ->my.js
 |- i18N -> message.properties

看起来 spring boot 或 thymeleaf 无法从可以找到模板的 Classloader/jar 文件中找到资源。你能帮我解决这个问题吗?我如何告诉 spring boot + thymeleaf 查看特定的类加载器以查找静态资源?

我已经尝试过设置 ClassLoaderTemplateResource 但没有成功。

@Bean
public ClassLoaderTemplateResource secondaryResouceResolver() throws IOException
{
    ClassLoaderTemplateResource secondaryResoucreResolver = new ClassLoaderTemplateResource(getCustomeClassLoader(),
        "static/", "UTF-8");

    return secondaryResoucreResolver;
}

提前感谢您的帮助!

【问题讨论】:

    标签: java spring spring-boot thymeleaf classloader


    【解决方案1】:

    我找不到任何可以使用 jar 文件或类加载器来指向外部静态资源的机制。因此,为了从不在类路径中的 jar 文件中指向静态资源(Js/css)和消息文件,您需要覆盖一些 Spring Boot 默认配置。首先,您需要在某个文件夹中提取 jar 文件,然后您需要覆盖 WebMvcConfigurer 接口的 addResourceHandlers() 方法,如下所示:

     @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry)
    {
        registry
          .addResourceHandler("js/**") /*This must be relative request url for js*/
          .addResourceLocations("file:/C:/MyStuff/jarfolder/js/")
          .setCachePeriod(3600)
          .resourceChain(true)
          .addResolver(new PathResourceResolver());
        
        registry
        .addResourceHandler("css/**")/*This must be relative request url for css*/
        .addResourceLocations("file:/C:/MyStuff/jarfolder/css/")
        .setCachePeriod(3600)
        .resourceChain(true)
        .addResolver(new PathResourceResolver());
    }
    

    为了从 jar 文件中引用消息源,而不是在类路径中。您需要提取它,然后提供它的路径,如下所示:

     @Bean
    public MessageSource messageSource() throws IOException
    {
        ReloadableResourceBundleMessageSource messageSource = 
            new ReloadableResourceBundleMessageSource();
       
        
        messageSource.setDefaultEncoding("UTF-8");
        messageSource.setUseCodeAsDefaultMessage(true);
        messageSource.addBasenames("classpath:i18n/messages");
      messageSource.addBasenames("file:/C:/MyStuff/jarfolder/messages");
        return messageSource;
    }
    

    这将用于从外部来源获取静态资源和消息来源。如果有人知道更好的解决方案,请在此处留下您的评论。

    【讨论】:

      【解决方案2】:

      如果我正确理解了您的要求,则您不需要编写此代码。只需转到 start.spring.io 并让该工具创建您的构建文件(maven 或 gradle)并选择 JAR 类型。将您的文件放在该工具创建的相关文件夹中。然后从您的 IDE 启动它。

      【讨论】:

      • 其实我需要动态地从jar中读取模板和静态资源(插件架构或者像OSGI这样的模块化应用)。我的 jar 文件是正确的。我使用自定义类加载器在应用程序中加载 jar 文件。现在应用程序通过 classloadertemplateresolver 访问模板,但我想有一种方法可以告诉百里香叶与模板关联的静态资源,但根据我的研究直到现在。另外,我明白了,我们必须通过springboot单独管理静态资源,它与thymeleaf无关。
      猜你喜欢
      • 2021-05-31
      • 1970-01-01
      • 2021-07-06
      • 2020-08-27
      • 1970-01-01
      • 2017-08-23
      • 2018-03-01
      • 2017-06-21
      • 2013-03-22
      相关资源
      最近更新 更多