2012-10-28 11 views
6

Używam programu maven i standardowego układu katalogu. Więc dodałem plik testdata.xml w folderze src/test/zasobów oraz Dodałem też jako:Jak odwołać się do pliku umieszczonego w folderze WEB-INF podczas korzystania z Arquillian?

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

w sposobie wdrażania, i potwierdzili, że tam jest. Spowoduje to, że plik pojawi się w /WEB-INF/testdata.xml. Teraz potrzebuję mieć odniesienie do tego pliku w moim kodzie i próbowałem kilku różnych getClass().getResourceAsStream(...) i ciągle zawodzę, więc potrzebuję teraz porady.

Potrzebuję go do testu integracji DBUnit. Czy to nie jest możliwe?

+2

To powinno być w ścieżce klasy do wykonaj 'Class.getResourseAsStream()'. Nie wszystko w WEB-INF jest umieszczone w ścieżce klas. Tylko zawartość folderu klas w WEB-INF jest dodawana do ścieżki klasy. Możesz uzyskać ścieżkę ścieżki kontekstowej i dołączyć do niej resztę lokalizacji. –

+0

Lub jeśli masz dostęp do 'ServletContext' możesz zrobić' servletContext.getRealPath ("/ WEB-INF/testdata.xml") '. –

+0

@BheshGurung Ale to się nie udaje. – LuckyLuke

Odpowiedz

17

Wariant A) Zastosowanie ServletContext.getResourceXXX()

Powinieneś mieć Aquillarian MockHttpSession i MockServletContext. Np:

@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 = ServletContext.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); 
    } 

Można tworzyć pliki zasobów & podkatalogi:

  1. internetowej modułu głównego dokumentu - zasoby są dostępne z poziomu przeglądarki i od zajęć
  2. WEB-INF/classes/- Zasoby są dostępne dla klas
  3. WEB-INF/lib/*. jar źródłowy jar - dostępny dla klas
  4. WEB-INF/lib/*. jar dedykowany tylko dla zasobów - dostępny dla klasy s
  5. WEB-INF/bezpośrednio w katalogu - dostępne dla klas. Tego właśnie prosisz.

We wszystkich przypadkach źródłem mogą być dostępne poprzez:

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

>

Będą one pakowane w pliku WAR i może być eksplodował w katalogach na wdrożonej mogą one serwera aplikacji lub pozostań w pliku WAR na serwerze aplikacji. Tak czy inaczej - to samo zachowanie dla dostępu do zasobów: użyj ServletContext.getResourceXXX().

Należy pamiętać, że zgodnie z ogólną zasadą (5) sam katalog najwyższego poziomu WEB-INF jest przeznaczony do użytku przez serwer.Jest "uprzejme", aby nie umieszczać tutaj bezpośrednio swoich zasobów sieciowych lub nie tworzyć bezpośrednio własnego katalogu. Zamiast tego lepiej użyć (2) powyżej.

JEE5 tutorial web modules JEE6 tutorial web modules

Wariant B): Użyj Class.getResourceXXX()

Najpierw przesunąć zasoby z katalogu WEB-INF do WEB-INF/classes (lub wewnątrz słoika WEB- INF/lib/*. Jar).

Jeśli klasa test jest:

  • com.abc.pkg.test.MyTest w pliku WEB-INF/classes/com/abc/pkg/test/MyTest.class

i plik zasobów jest

  • WEB-INF/classes/com/abc/pkg/test/resources/testdata.xml (lub równowartość w pliku jar)

dostęp do plików za pomocą względna lokalizację pliku, za pośrednictwem Java ClassLoader - stwierdza Foldery/Jars względem Classpath:

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

dostępu do plików Korzystanie pełny pakiet podobny Kwalifikacje, Korzystanie Java ClassLoader - stwierdza Foldery/Jars względem Classpath :

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

Mam nadzieję, że to nails! @B)

+0

Dzięki. To też mi pomogło. – CodeBlue

+0

Plik java.io.File nie ma konstruktora dla pliku java.net.URL, dlatego plik resfile = new File (url); Konwersje nie będą nawet kompilować – JanM

+0

Jak stwierdza @JanM, plik java.io.File nie ma konstruktora java.net.URL. – Doug

4

Sposób, aby uzyskać dostęp do plików w WEB-INF odbywa się za pomocą trzech metod ServletContext:

  1. getResource("/WEB-INF/testdata.xml") daje URL
  2. getResourceAsStream daje strumień wejściowy
  3. getRealPath daje ścieżkę na twardym odpowiedni plik.

Pierwsze dwa powinny zawsze działać, trzecia może się nie powieść, jeśli nie ma bezpośredniej korespondencji między ścieżkami zasobów i plikami na dysku, na przykład, jeśli aplikacja internetowa jest uruchamiana bezpośrednio z pliku WAR, a nie z rozpakowanego katalogu Struktura.

+1

Jak uzyskać obiekt kontekstu serwletu, gdy używam Arquilliana? – LuckyLuke

1

Dodaj klasę do projektu:

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

Teraz tam, gdzie chcesz, aby uzyskać pełną ścieżkę do pliku "testdata.xml" używania tego lub podobnego kodu:

String testdata_file_location = Init.getWebInfPath() + "/testdata.xml"; 
+0

HI Abhishek: Próbowałem ur code..I utrzymywałem plik .properties wewnątrz WEB-INF .. kiedy drukuję plik testdata_file_location to drukuje jak E: \ ec \ temp.properties ..To nie wiem dlaczego to robi. Jak odczytać z niego właściwości – sree

+0

@ Czy realizujesz projekt za pomocą jakiegoś IDE? i czy możesz nam również powiedzieć wersję Tomcat lub GlassFish czy cokolwiek innego? wygląda na to, że ec.war został wdrożony na dysku E: i/lub właściwość 'docBase' w elemencie /conf/catalina/localhost/ec.xml' Context' wskazuje taką lokalizację. Sprawdź również, czy używasz 'web_inf_path.lastIndexOf (WEB_INF_DIR_NAME) + WEB_INF_DIR_NAME.length()' lub 'web_inf_path.lastIndexOf (WEB_INF_DIR_NAME)' z powyższego kodu (tj. Przypadkowo opuściłeś '+ WEB_INF_DIR_NAME.length()' część tego kod?) –

+0

Cześć Abhishek mam działa. Poniżej znajduje się mój kod prop.load (nowy FileInputStream ("./ WEB-INF/temp.properties")); – sree

2

Dzisiaj byłem boryka się z tym samym wymaganiem i nie znalazła żadnej pełnej próbki źródłowej, więc tutaj idę z najmniejszym samodzielnym testem, który mogłem połączyć:

@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); 
    } 
} 

W swoim projekcie plik hello-kitty.png przechodzi na src/test/resources. W archiwum testowym jest ono umieszczane w folderze /WEB-INF/classes, który znajduje się w ścieżce klas, a zatem można go załadować za pomocą tego samego modułu ładującego klasy, co kontener używany w scenariuszu testowym.

IOUtils pochodzi z apache commons-io.

Uwaga dodatkowa: Jedna rzecz, która mnie do zarysowania moja głowa była związana z spacji w ścieżce do mojego serwera i sposób getResourceAsStream() ucieka takie znaki specjalne: sysLoader.getResource() problem in java

+0

Dlaczego nie skorzystać z interfejsu API Java 7? – BonanzaOne

Powiązane problemy