我正在使用以下代码查找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
这是资源的工作和工作正常的地方。
当我将war文件导出到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
这不是资源的位置,导致文件未找到异常。
我做错了什么?
答案 0 :(得分:2)
理想情况下,您应该:
ServletContext.getResource("/abc.html")
访问WebApp中的内容。 /WEB-INF/classes/
来存储静态资源。使用/WEB-INF/resources/
由于webapp容器可以移动内容以满足其自身需求。
(有关详细信息,请参阅javax.servlet.ServletContext.getResource(String path)
上的javadoc)
此外,实用程序类不应该依赖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);
}
}
答案 1 :(得分: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()通常不能用于子类或自动代理方案。