7

我正在使用 Maven 和标准目录布局。所以我在 src/test/resources 文件夹中添加了一个 testdata.xml 文件,我也将它添加为:

.addAsWebInfResource("testdata.xml", "testdata.xml")

在部署方法中,我已经确认它在那里。这将使文件出现在/WEB-INF/testdata.xml. 现在我需要在我的代码中引用这个文件,我尝试了几种不同的方法getClass().getResourceAsStream(...)并且一次又一次地失败,所以我现在需要一些建议。

我的 DBUnit 集成测试需要它。这不可能吗?

4

4 回答 4

19

选项 A) 使用 ServletContext.getResourceXXX()

你应该有一个 Aquillarian MockHttpSession 和一个 MockServletContext。例如:

@Test
   public void myTest()
   {
      HttpSession session = new MockHttpSession(new MockServletContext());
      ServletLifecycle.beginSession(session);

      ..testCode..

      // You can obtain a ServletContext (will actually be a MockServletContext 
      // implementation):
      ServletContext sc = session.getServletContext();
      URL url = sc.getResource("/WEB-INF/testdata.xml")
      Path resPath = new Path(url);
      File resFile = new File(url);
      FileReader resRdr = new FileReader(resFile);
      etc...

      ..testCode..

      ServletLifecycle.endSession(session);
   }

您可以在以下位置创建资源文件和子目录:

  1. Web 模块文档根目录 - 可以从浏览器和类访问资源
  2. WEB-INF/classes/ - 资源可以被类访问
  3. WEB-INF/lib/*.jar 源 jar - 类可访问
  4. WEB-INF/lib/*.jar 专用的仅资源 jar - 可供类访问
  5. WEB-INF/ 直接在目录中 - 类可访问。这就是你所要求的。

在所有情况下,都可以通过以下方式访问资源:

URL url = sc.getResource("/<path from web doc root>/<resourceFileName>");
OR    
InputStream resIS = sc.getResourceAsStream("/<path from web doc root>/<resourceFileName>");

>

这些将被打包到 WAR 文件中,并且可能会分解到已部署的应用服务器上的目录中,或者它们可能会保留在应用服务器上的 WAR 文件中。无论哪种方式 - 访问资源的行为相同:使用 ServletContext.getResourceXXX()。

请注意,作为一般原则,(5) 顶级 WEB-INF 目录本身是供服务器使用的。不将您的网络资源直接放在此处或直接在此处创建自己的目录是“礼貌的”。相反,最好使用上面的(2)。

JEE5 教程网络模块 JEE6 教程网络模块

选项 B):使用 Class.getResourceXXX()

首先将资源从 WEB-INF 文件夹移到 WEB-INF/classes 中(或在 jar WEB-INF/lib/*.jar 中)。

如果您的测试课程是:

  • com.abc.pkg.test.MyTest 在文件 WEB-INF/classes/com/abc/pkg/test/MyTest.class

你的资源文件是

  • WEB-INF/classes/com/abc/pkg/test/resources/testdata.xml(或jar文件中的等价物)

使用相对文件位置访问文件,通过 Java 类加载器 - 查找相对于类路径的文件夹/罐子:

java.net.URL resFileURL = MyTest.class.getResource("resources/testdata.xml");
File resFile = new File(fileURL);    
OR
InputStream resFileIS = 
     MyTedy.class.getResourceAsStream("resources/testdata.xml");

使用完整的类包限定访问文件,使用 Java 类加载器 - 查找相对于类路径的文件夹/罐子:

java.net.URL resFileURL = MyTest.class.getResource("/com/abc/pkg/test/resources/testdata.xml");
File resFile = new File(fileURL);        
OR 
InputStream resFileIS = 
     MyTest.class.getResourceAsStream("/com/abc/pkg/test/resources/testdata.xml");   
OR 
java.net.URL resFileURL = MyTest.class.getClassLoader().getResource("com/abc/pkg/test/resources/testdata.xml");
File resFile = new File(fileURL);       
OR 
InputStream resFileIS = 
     MyTest.class.getClassLoader().getResourceAsStream("com/abc/pkg/test/resources/testdata.xml");

希望能搞定!@B)

于 2012-11-05T05:34:17.857 回答
5

访问文件的方式WEB-INF是通过以下三种方法ServletContext

  1. getResource("/WEB-INF/testdata.xml")给你一个网址
  2. getResourceAsStream给你一个输入流
  3. getRealPath为您提供相关文件在磁盘上的路径。

前两个应该始终有效,如果资源路径和磁盘上的文件之间没有直接对应关系,第三个可能会失败,例如,如果您的 Web 应用程序直接从 WAR 文件而不是解压缩的目录结构运行。

于 2012-11-02T21:05:48.027 回答
2

今天我在同样的要求上苦苦挣扎,还没有找到任何完整的源样本,所以我在这里进行了我可以放在一起的最小的自包含测试:

@RunWith(Arquillian.class)
public class AttachResourceTest {

    @Deployment
    public static WebArchive createDeployment() {
        WebArchive archive =  ShrinkWrap.create(WebArchive.class).addPackages(true, "org.apache.commons.io")
                .addAsWebInfResource("hello-kitty.png", "classes/hello-kitty.png");             
        System.out.println(archive.toString(true));
        return archive;
    }

    @Test
    public void attachCatTest() {
        InputStream stream = getClass().getResourceAsStream("/hello-kitty.png");
        byte[] bytes = null;
        try {
            bytes = IOUtils.toByteArray(stream);
        } catch (IOException e) {
            e.printStackTrace();
        }   
        Assert.assertNotNull(bytes);
    }
}

在您的项目中 hello-kitty.png 文件转到src/test/resources。在测试存档中,它被打包到类路径上的/WEB-INF/classes文件夹中,因此您可以使用与用于测试场景的容器相同的类加载器来加载它。

IOUtils 来自 apache commons-io。

附加说明:让我摸不着头脑的一件事与我的服务器路径中的空格以及 getResourceAsStream() 转义此类特殊字符的方式有关:java中的 sysLoader.getResource() 问题

于 2014-09-10T16:12:34.190 回答
1

将此类添加到您的项目中:

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

public class Init {
    private static final String WEB_INF_DIR_NAME="WEB-INF";
    private static String web_inf_path;
    public static String getWebInfPath() throws UnsupportedEncodingException {
        if (web_inf_path == null) {
            web_inf_path = URLDecoder.decode(Init.class.getProtectionDomain().getCodeSource().getLocation().getPath(), "UTF8");
            web_inf_path=web_inf_path.substring(0,web_inf_path.lastIndexOf(WEB_INF_DIR_NAME)+WEB_INF_DIR_NAME.length());
        }
        return web_inf_path;
    }
}

现在,无论您想获取文件的完整路径,请"testdata.xml"使用以下代码或类似代码:

String testdata_file_location = Init.getWebInfPath() + "/testdata.xml";
于 2012-11-06T06:57:33.670 回答