允许Apache的FreeMarker模板引擎从Resources文件夹以外加载模板

6

我使用Spring Initilizr创建了一个Spring Boot应用程序。然后,我在项目中包含了Apache的Freemarker模板引擎,以加载模板。该引擎默认从“src/main/resources/templates/”文件夹中加载模板。

我正在尝试在用户访问网页“http://localhost:8080”时作为模板加载一个简单的index.ftl文件。但我需要从“src/main/webapp/”文件夹加载模板。每当我尝试从resources文件夹之外加载模板时,模板引擎无法找到模板。

我查阅了各种教程和Stack Overflow的问题。没有一个回答我的问题,而我因为引擎无法找到文件而陷入了404错误中。

文件结构如下:

|-src
|---main
|-----java
|-------MainApplication.java
|-------controllers
|---------ViewController.java
|-----resources
|-------static
|-------templates
|-------application.properties
|-----webapp
|-------index.ftl

经过大量查找,我发现一篇文章建议更改模板引擎搜索文件的位置。它建议在application.properties中添加以下几行:

spring.freemarker.enabled=true
spring.freemarker.template-loader-path=classpath:src/main/webapp/

这似乎完全不起作用。

当我访问网页http://localhost:8080时,我试图解决简单的索引页面。 我编写了以下代码来映射ViewController.java中的HTTP请求:

@RequestMapping("/")
public ModelAndView home(Model model)
{
    return new ModelAndView("index");
}

我不确定是否完全理解正确或者是否遗漏了某些配置。


使用源代码路径(src)几乎从来都不是正确的选择(考虑到您只部署jarwarear,它们都不包含源代码)。由于文件位于servlet上下文中,因此您应该将/作为模板加载器路径(通常意味着servlet上下文资源,而不是类路径资源)。 - ddekany
好的。谢谢。我会对代码进行更改。但是,我如何确保上下文路径可以设置为指向webapps文件夹呢?虽然这很傻,但真的让我头疼。 - Shivam Naik
1
https://dev59.com/OLLma4cB1Zd3GeqPh-RU#55451851 可能会有帮助/重复警告!!! - xerx593
  1. 过时的
  2. 尝试使用 file:// 前缀/协议
  3. 如果以上所有方法都失败了:覆盖(FreeMarkerConfigurer)bean(作为大多数重复问题中被接受的解决方案)
- xerx593
1
对于Spring Boot静态上下文,请使用spring.mvc.static-path-pattern=,请参见https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html。 - user7294900
显示剩余8条评论
2个回答

1

来自Spring文档:

如果您的应用程序打包成jar,请不要使用src/main/webapp目录。尽管此目录是常见标准,但它仅适用于war打包,并且在生成war时大多数构建工具都会默默忽略它。

src/main/webapp与Web Archive相关,并且在生成war时将由Maven War插件打包。

假设您需要一个单独的位置来保存ftl模板,并且仍然想打包为jar,您可以按照以下步骤操作。

在pom文件的构建中添加资源条目,以便资源插件可以将该目录复制到类路径中。

<build>
    <resources>
      <resource>
         <directory>src/main/webapp</directory>
     </resource>
    <resources>
<build>

将加载器路径更改为从类路径的 ROOT 读取。
spring.freemarker.template-loader-path=classpath:

如果只是针对ftl模板,我会将目录更改为src/main/ftls,以避免混淆,并在资源中进行更新。 更新

我实际上想要构建一个WAR部署包

您必须使用war插件来构建war。在pom中添加插件并将打包方式更改为war。
有关传统部署的更多信息:https://docs.spring.io/spring-boot/docs/current/reference/html/howto-traditional-deployment.html#howto-create-a-deployable-war-file

你试过我的答案了吗?如果有问题,请告诉我。你不应该为jar包创建一个webapp文件夹。这不是一个好的做法,应该避免。它会让应用程序看起来像一个war项目。你应该遵循Spring Boot的建议,将所有文件放在资源文件夹内。任何在资源文件夹下的文件都会被打包到jar中。 - s7vr
我检查了你的答案,并意识到我实际上想要构建一个WAR部署包。我也修改了我的问题。感谢你的启示。但是,我的模板引擎无法从webapp文件夹中获取模板。 - Shivam Naik
您需要使用“war”插件来构建“war”包。在pom文件中添加该插件并将类型更改为“war”。 - s7vr
非常感谢,伙计。我将包装转换为WAR。将 spring.freemarker.template-loader-path=classpath: 添加到 application.properties 中。然后将ftl文件存储在 src/main/webapp/resources/ 文件夹中。现在一切都完美地工作了。 - Shivam Naik
为什么不根据所做的更改编辑您的答案?这可能有助于其他遇到类似问题的人。 将webapp作为文件夹添加而不是webapps是我的一个愚蠢错误。我已经修改了问题。 :) - Shivam Naik
显示剩余2条评论

0

编辑

在嵌入式Tomcat中,您可以在application-properties中定义静态资源路径。

 spring.mvc.static-path-pattern=

如果您部署到Tomcat,可以在Tomcat中定义{{link1:静态上下文}},其中可以保存Freemarker文件。
 <Context docBase="/home/stuff" path="/static" />

<Host>元素内添加了一个<Context>元素。Context有两个属性:docBase是包含静态文件的磁盘目录,path是您希望在其上提供文件的URL。

实际上我没有外部安装Tomcat。Spring会自动初始化它。所以,我实际上找不到你提到的server.xml文件。 - Shivam Naik
@ShivamNaik 查看Spring静态资源的选项 https://www.baeldung.com/spring-mvc-static-resources - user7294900
我会仔细看一下,如果可以的话会回复您。谢谢。 - Shivam Naik
是的,@user7294900。我确实尝试了你给出的第一个解决方案。尽管它没有解决我的问题,但现在问题已经解决了。我已经将可行的答案选为正确答案 :) - Shivam Naik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接