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

Java 使用Arquillian时,如何引用放置在WEB-INF文件夹中的文件?,java,jakarta-ee,maven,dbunit,Java,Jakarta Ee,Maven,Dbunit,我正在使用maven和标准目录布局。因此,我在src/test/resources文件夹中添加了一个testdata.xml文件,并将其添加为: .addAsWebInfResource("testdata.xml", "testdata.xml") 在部署方法中,我已经确认了它的存在。这将使文件出现在/WEB-INF/testdata.xml中。现在我需要在代码中引用这个文件,我尝试了几种不同的getClass().getResourceAsStream(…),但一次又一次失败,所以我现在需

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

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


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

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

  • getResource(“/WEB-INF/testdata.xml”)
    提供一个URL
  • getResourceAsStream
    提供一个输入流
  • getRealPath
    提供相关文件在磁盘上的路径
  • 前两种方法应该始终有效,如果资源路径和磁盘上的文件之间没有直接的对应关系,第三种方法可能会失败,例如,如果您的web应用程序直接从WAR文件而不是解包的目录结构运行。

    选项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);
       }
    
    您可以在以下位置创建资源文件和子目录:

  • 可以从浏览器和类访问web模块文档根资源
  • WEB-INF/classes/-类可以访问资源
  • WEB-INF/lib/*.jar源jar-可供类访问
  • WEB-INF/lib/*.jar专用资源专用jar-可供类访问
  • WEB-INF/直接在目录中-可供类访问。这就是你想要的
  • 在所有情况下,都可以通过以下方式访问资源:

    URL url = sc.getResource("/<path from web doc root>/<resourceFileName>");
    OR    
    InputStream resIS = sc.getResourceAsStream("/<path from web doc root>/<resourceFileName>");
    
    使用Java类加载器(查找相对于类路径的文件夹/JAR),使用完整的包(如限定)访问文件:

    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) 将此类添加到项目中:

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

    今天,我正在努力满足同样的需求,但还没有找到任何完整的源代码示例,因此,这里我将进行一个最小的自包含测试:

    @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来自apachecommons io

    补充说明:
    让我抓狂的一件事与服务器路径中的空格以及getResourceAsStream()转义这些特殊字符的方式有关:

    应该在类路径中执行
    Class.getResourceAsStream()
    。不是WEB-INF中的所有内容都放在类路径中。只有WEB-INF中“类”文件夹的内容才会添加到类路径中。您可以获取上下文路径的路径并将位置的其余部分附加到该路径。或者,如果您有权访问
    ServletContext
    的话,您可以执行
    ServletContext.getRealPath(“/WEB-INF/testdata.xml”)
    @Dude,这个XML文件是包含测试中使用的数据的DbUnit平面XML文件吗?当我使用Arquillian时,如何获取servlet上下文对象?谢谢。这对我也有帮助。java.io.File没有java.net.URL的构造函数,因此您的文件resFile=newfile(URL);转换甚至不会编译@JanM states,java.io.File没有java.net.URL构造函数。自java 1.4以来,该文件就有一个构造函数文件(URI)。URL扩展了URI.Oops。URL实际上并没有扩展URI,URL.toURI()声明了一个选中的异常。阿披舍克:我试过你的代码..我把.properties文件保存在WEB-INF里面。。当我打印testdata\u文件\u位置时,它像E:\ec\temp.properties一样打印。所以我不知道它为什么这样做。那么如何从中读取属性呢it@sree您正在使用IDE运行项目吗?你能告诉我们Tomcat或Glassfish的版本或你正在使用的任何东西吗?看起来ec.war已经部署在E:drive中,和/或/conf/catalina/localhost/ec.xml的
    上下文
    元素中的
    docBase
    属性指向这样的位置。另外,请检查您是否正在使用
    web\u inf\u path.lastIndexOf(web\u inf\u DIR\u NAME)+web\u inf\u DIR\u NAME.length()
    web\u inf\u path.lastIndexOf(web\u inf\u DIR\u NAME)
    来自上述代码(即,您意外地离开了
    +web\u inf\u DIR\u NAME.length()
    该代码的一部分。):HISHEK我开始工作了。下面是我的代码道具(新的FileInputStream(“./WEB-INF/temp.properties”);为什么不使用Java7文件API?
    @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);
        }
    }