使用Arquillian时,如何引用放在WEB-INF文件夹中的文件?

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

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

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

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

选项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 source jar – 类可访问
  4. WEB-INF / lib / * .jar专用资源专用jar – 类可访问
  5. WEB-INF /直接在目录中 – 可访问类 。 这就是你要求的。

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

 URL url = sc.getResource("//"); OR InputStream resIS = sc.getResourceAsStream("//"); 

>

这些将打包到WAR文件中,并可以展开到已部署的应用服务器上的目录中,也可以保留在应用服务器上的WAR文件中。 无论哪种方式 – 访问资源的行为相同:使用ServletContext.getResourceXXX()。

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

JEE5教程Web模块 JEE6教程Web模块

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

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

如果您的测试类是:

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

你的资源文件是

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

使用相对文件位置访问文件,通过Java ClassLoader – 找到相对于Classpath的文件夹/ Jars:

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

访问文件使用完全类似于Package的资格,使用Java ClassLoader – 查找相对于Classpath的文件夹/ Jars:

 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)

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

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

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

今天我一直在努力满足相同的要求,并且没有找到任何完整的源代码示例,所以在这里我采用最小的自包含测试我可以放在一起:

 @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()问题

将此类添加到项目中:

 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";