1

我正在使用以下代码查找 Freemarker 从 HTML 创建 PDF 所需的资源。

public static URL lookupResource(String resource) {
    System.out.println("Looking up resource: " + resource);
    ClassLoader classLoader =  Thread.currentThread().getContextClassLoader();      
    URL templateFileUrl = classLoader.getResource(resource);        
    System.out.println("path: " + templateFileUrl.getPath());   
    return templateFileUrl;
}

在 Eclipse Maven 项目中的 Jetty 上运行,我得到以下信息:

Looking up resource: abc.html
path: /C:/Projects/WebDocs/EclipseProjects/webdocs2/webdocs/target/classes/abc.xhtml

这是资源所在并且工作正常的地方。

当我将战争文件导出到 Tomcat 时,资源被放入 /C:/Program%20Files/Apache%20Software%20Foundation/Tomcat%207.0/webapps/webdocs

在Tomcat上运行我得到以下信息:

Looking up resource: abc.html
path: /C:/Program%20Files/Apache%20Software%20Foundation/Tomcat%207.0/webapps/webdocs/WEB-INF/classes/abc.xhtml

这不是资源所在的位置,会导致文件未找到异常。

我究竟做错了什么?

4

2 回答 2

2

理想情况下,您应该:

因为 webapp 容器可以移动内容以满足自己的需要。

(有关详细信息,请参阅 javadoc javax.servlet.ServletContext.getResource(String path)

此外,实用程序类不应依赖Thread.currentThread().getContextClassLoader(). 相反,使用从请求资源的类获得的类加载器。

public class MyClass {
  public void doIt() {
    URL url = Utils.getResource(this,"abc.html");
  }
}

public final class Utils {
  public static URL getResource(Object obj, String resource) {
    return obj.getClass().getClassLoader().getResource(resource);
  }
}
于 2013-09-27T22:43:48.780 回答
0

如果您想将模板(或任何其他资源)存储为 jar 的一部分,我会查看代码以改用 InputStreams。要获取模板,请使用this.getClass().getClassLoader().getResourceAsStream()(甚至更好,this.getClass().getResourceAsStream()并以包结构组织资源)。之后,使用构造Template(InputStream stream)函数构造模板。这样,即使您的 jar/war 没有“分解”成物理文件,您的代码也能正常工作。

要使用this.getClass().getResourceAsStream(),当作为类文件编译到 jar 中时,您的资源必须位于同一目录中。如果您使用 maven,请将资源放在"resources/path/to/yourpackage/resource.file"中。注意:更安全的方法是为此解决方案使用类名本身,例如 MyClass.getResourceAsStream(),因为 this.getClass() 通常在子类化或自动代理场景中不起作用。

于 2013-09-28T10:03:04.683 回答