web-dev-qa-db-ja.com

Arquillianを使用しているときに、WEB-INFフォルダーに配置されているファイルを参照するにはどうすればよいですか?

私はMavenと標準のディレクトリレイアウトを使用しています。そこで、src/test/resourcesフォルダーにtestdata.xmlファイルを追加し、次のように追加しました。

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

展開方法で、そこにあることを確認しました。これにより、ファイルが_/WEB-INF/testdata.xml_に表示されます。ここで、コードにこのファイルへの参照を含める必要があり、いくつかの異なるgetClass().getResourceAsStream(...)を試しましたが、何度も失敗したため、今すぐアドバイスが必要です。

DBUnit統合テストに必要です。これは不可能ですか?

7
LuckyLuke

オプションA)ServletContext.getResourceXXX()を使用します

AquillarianMockHttpSessionと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/*。jarsourcejar-クラスにアクセス可能
  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ファイルにパッケージ化され、デプロイされたアプリサーバー上のディレクトリに展開される可能性がありますORアプリサーバー上のWARファイル内にとどまる可能性があります。どちらの方法でも-リソースにアクセスする場合と同じ動作: ServletContext.getResourceXXX()を使用します。

一般原則として、(5)最上位のWEB-INFディレクトリ自体はサーバーによる使用を目的としていることに注意してください。 Webリソースをここに直接配置したり、独自のディレクトリをここに直接作成したりしないのは「礼儀正しい」ことです。代わりに、上記の(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 /My​​Test.classのcom.abc.pkg.test.MyTest

そしてあなたのリソースファイルは

  • WEB-INF/classes/com/abc/pkg/test/resources/testdata.xml(またはjarファイル内の同等のもの)

Java ClassLoaderを介して相対ファイル位置を使用してファイルにアクセスします-クラスパスに関連するフォルダー/ Jarを検索します:

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 ClassLoaderを使用して-クラスパスに関連するフォルダー/ジャーを検索します:

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)

19
Glen Best

_WEB-INF_の下のファイルにアクセスする方法は、ServletContextの3つの方法です。

  1. getResource("/WEB-INF/testdata.xml")はあなたにURLを与えます
  2. getResourceAsStreamは入力ストリームを提供します
  3. getRealPathは、関連するファイルのディスク上のパスを示します。

最初の2つは常に機能するはずですが、リソースパスとディスク上のファイルが直接対応していない場合、たとえばWebアプリケーションが解凍されたディレクトリ構造ではなくWARファイルから直接実行されている場合、3つ目は失敗する可能性があります。

5
Ian Roberts

今日、私は同じ要件に苦労していて、完全なソースサンプルが見つからなかったので、ここでは、まとめることができる最小の自己完結型テストを使用します。

@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()がそのような特殊文字をエスケープする方法に関連していました: sysLoader.getResource()の問題Java

2
JanM

このクラスをプロジェクトに追加します。

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";
1
Abhishek Oza