Jetty和Tomcat之间的getResource中的差异会导致找不到文件异常

时间:2013-09-27 22:03:09

标签: 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 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

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

我做错了什么?

2 个答案:

答案 0 :(得分:2)

理想情况下,您应该:

由于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()通常不能用于子类或自动代理方案。