Java Jetty和Tomcat在getResource中的差异导致文件找不到异常

Java Jetty和Tomcat在getResource中的差异导致文件找不到异常,java,tomcat,resources,jetty,filenotfoundexception,Java,Tomcat,Resources,Jetty,Filenotfoundexception,我使用以下代码查找Freemarker从HTML创建PDF所需的资源 public static URL lookupResource(String resource) { System.out.println("Looking up resource: " + resource); ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); URL templateFi

我使用以下代码查找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
Looking up resource: abc.html
path: /C:/Program%20Files/Apache%20Software%20Foundation/Tomcat%207.0/webapps/webdocs/WEB-INF/classes/abc.xhtml
这就是资源所在的位置,工作正常

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

在Tomcat上运行时,我得到以下结果:

Looking up resource: abc.html
path: /C:/Projects/WebDocs/EclipseProjects/webdocs2/webdocs/target/classes/abc.xhtml
Looking up resource: abc.html
path: /C:/Program%20Files/Apache%20Software%20Foundation/Tomcat%207.0/webapps/webdocs/WEB-INF/classes/abc.xhtml
这不是资源所在的位置,并导致文件未找到异常

我做错了什么?

理想情况下,你应该:

  • 用于从WebApp中访问内容
  • 不要使用
    /WEB-INF/classes/
    存储静态资源。使用
    /WEB-INF/resources/
因为webapp容器可以根据自己的需要移动内容

(有关详细信息,请参阅上的javadoc)

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

公共类MyClass{
公共无效doIt(){
URL=Utils.getResource(这是“abc.html”);
}
}
公共最终类UTIL{
公共静态URL getResource(对象对象对象,字符串资源){
返回obj.getClass().getClassLoader().getResource(资源);
}
}

如果您想将模板(或任何其他资源)存储为jar的一部分,我将检查代码以使用InputStreams。要获取模板,请使用
this.getClass().getClassLoader().getResourceAsStream()
(或者更好地使用
this.getClass().getResourceAsStream()
并在包结构中组织资源)。之后,使用constructor
Template(InputStream)
构建模板。这样,即使在jar/war没有“分解”成物理文件的情况下,代码也可以工作


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

感谢您的回复。这可以在Web容器中工作,但是代码不一定总是在servlet容器中运行,并且提供资源的实用程序类没有访问ServletContext的权限。我可以通过方法链将ServletContext传递给实用程序类,或者使用线程局部变量,但还有另一个问题。代码需要在独立程序和不在web容器中运行的单元测试中运行。它只需要一个html模板和一个映射来生成PDF输出。然后不要将资源放在
/WEB-INF/classes/
中,而是将资源放在
/WEB-INF/lib/
中的jar文件中。这样您将获得最大的兼容性。@JoakimErdfelt请提供完整的solution@JoakimErdfelt我是这样做的:publicstaticintemp\u LEDGER=6.私有静态字符串EMP\u LEDGER\u PATH=“\\employee\u LEDGER\\EmployeeLedger.jasper”;案例6:返回getParentDir()+EMP\u LEDGER\u路径;