2012-10-28 13 views
6

Tôi đang sử dụng maven và bố cục thư mục chuẩn. Vì vậy, tôi đã thêm tệp testdata.xml vào thư mục src/test/resources và tôi cũng đã thêm tệp đó vào:Làm cách nào để tham chiếu tệp được đặt trong thư mục WEB-INF khi sử dụng Arquillian?

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

trong phương pháp triển khai và tôi đã xác nhận rằng nó ở đó. Điều này sẽ làm cho tệp xuất hiện trong /WEB-INF/testdata.xml. Bây giờ tôi cần phải có một tham chiếu đến tập tin này trong mã của tôi và tôi đã thử một số khác nhau getClass().getResourceAsStream(...) và thất bại một lần nữa và một lần nữa vì vậy tôi cần một số tư vấn ngay bây giờ.

Tôi cần nó cho thử nghiệm tích hợp DBUnit của mình. Điều này là không thể?

+2

Nó phải ở trong classpath để làm 'Class.getResourseAsStream()'. Không phải mọi thứ bên trong WEB-INF đều được đặt trong classpath. Chỉ nội dung của thư mục lớp trong WEB-INF mới được thêm vào đường dẫn lớp. Bạn có thể nhận được đường dẫn của đường dẫn ngữ cảnh và nối nó với phần còn lại của vị trí. –

+0

Hoặc nếu bạn có quyền truy cập vào 'ServletContext', bạn có thể thực hiện' servletContext.getRealPath ("/ WEB-INF/testdata.xml") '. –

+0

@BheshGurung Nhưng điều đó không thành công. – LuckyLuke

Trả lời

17

Lựa chọn A) Sử dụng ServletContext.getResourceXXX()

Bạn nên có một MockHttpSession Aquillarian và MockServletContext. Ví dụ:

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

Bạn có thể tạo các file tài nguyên & thư mục con trong:

  1. module gốc tài liệu web - nguồn lực có thể truy cập từ trình duyệt và từ lớp
  2. WEB-INF/classes/- nguồn lực có thể truy cập vào các lớp học
  3. WEB-INF/lib/*. jar nguồn jar - có thể truy cập vào các lớp học
  4. WEB-INF/lib/*. jar jar chỉ dành riêng cho tài nguyên - có thể truy cập vào classe s
  5. WEB-INF/trực tiếp trong thư mục - có thể truy cập vào các lớp. Đây là những gì bạn đang yêu cầu.

Trong mọi trường hợp tài nguyên có thể được truy cập thông qua:

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

>

Những điều này sẽ được đóng gói vào tập tin WAR và có thể bùng nổ vào thư mục trên máy chủ ứng dụng được triển khai hoặc họ có thể ở trong tệp WAR trên máy chủ ứng dụng. Dù bằng cách nào - cùng một hành vi để truy cập tài nguyên: sử dụng ServletContext.getResourceXXX().

Lưu ý rằng theo nguyên tắc chung, (5) thư mục WEB-INF cấp cao nhất được dự định để sử dụng bởi máy chủ.Đó là 'lịch sự' không đặt tài nguyên web của bạn trực tiếp tại đây hoặc tạo thư mục của riêng bạn trực tiếp tại đây. Thay vào đó, tốt hơn để sử dụng (2) ở trên.

JEE5 tutorial web modules JEE6 tutorial web modules

Lựa chọn B): Sử dụng Class.getResourceXXX()

Đầu tiên di chuyển các nguồn lực ra khỏi thư mục WEB-INF vào WEB-INF/classes (hoặc bên trong một lọ WEB- INF/lib/*. Jar).

Nếu lớp thử nghiệm của bạn là:

  • com.abc.pkg.test.MyTest trong file WEB-INF/classes/com/abc/pkg/test/MyTest.class

và tập tin tài nguyên của bạn là

  • WEB-INF/classes/com/abc/pkg/test/nguồn/testdata.xml (hoặc tương đương trong một file jar)

truy cập tập tin sử dụng tương đối File Location, thông qua Java ClassLoader - tìm thấy thư mục/Chum so với 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"); 

truy cập tập tin Sử dụng đầy đủ trọn gói giống như Trình độ chuyên môn, Sử dụng Java ClassLoader - tìm thấy thư mục/Chum so với 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"); 

Mong rằng móng tay! @B)

+0

Cảm ơn. Điều này đã giúp tôi. – CodeBlue

+0

java.io.File không có hàm tạo cho java.net.URL do đó File resFile = new File (url); chuyển đổi thậm chí sẽ không biên dịch – JanM

+0

Vì trạng thái @JanM, java.io.File không có hàm tạo java.net.URL. – Doug

4

Cách để truy cập các tập tin dưới WEB-INF là thông qua ba phương pháp ServletContext:

  1. getResource("/WEB-INF/testdata.xml") mang đến cho bạn một URL
  2. getResourceAsStream mang đến cho bạn thêm một input stream
  3. getRealPath cung cấp cho bạn đường dẫn trên đĩa của tệp có liên quan.

Hai đầu tiên phải luôn hoạt động, thứ ba có thể thất bại nếu không có sự tương ứng trực tiếp giữa đường dẫn tài nguyên và tệp trên đĩa, ví dụ như ứng dụng web của bạn đang chạy trực tiếp từ tệp WAR chứ không phải thư mục chưa giải nén kết cấu.

+1

Làm thế nào để có được một đối tượng bối cảnh servlet khi tôi sử dụng Arquillian? – LuckyLuke

1

Thêm lớp này để dự án của bạn:

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

Bây giờ bất cứ nơi nào bạn muốn nhận được đường dẫn đầy đủ của tập tin "testdata.xml" sử dụng này hoặc mã tương tự:

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

HI Abhishek: Tôi đã thử mã ur .. Tôi đã lưu tệp .properties bên trong WEB-INF .. khi tôi in testdata_file_location nó đang in như E: \ ec \ temp.properties ..So i dont know why it is doing. Vì vậy, làm thế nào để đọc các thuộc tính từ nó – sree

+0

@sree là bạn đang chạy dự án của bạn bằng cách sử dụng một số IDE? và bạn có thể cho chúng tôi biết phiên bản của Tomcat hoặc Glassfish hay bất cứ thứ gì bạn đang sử dụng không? trông giống như ec.war đã được triển khai trong E: drive, và/hoặc thuộc tính 'docBase' trong phần tử' Context' của phần tử /conf/catalina/localhost/ec.xml trỏ đến vị trí đó. Ngoài ra, hãy kiểm tra xem bạn có đang sử dụng 'web_inf_path.lastIndexOf (WEB_INF_DIR_NAME) + WEB_INF_DIR_NAME.length()' hoặc 'web_inf_path.lastIndexOf (WEB_INF_DIR_NAME)' từ mã ở trên không (nghĩa là có u vô tình trái '+ WEB_INF_DIR_NAME.length()' một phần của code?) –

+0

Hi Abhishek tôi đã làm việc ..bây giờ là mã prop.load của tôi (tệp FileInputStream mới ("./ WEB-INF/temp.properties")); – sree

2

Hôm nay tôi đã đấu tranh với cùng một yêu cầu và không tìm thấy bất kỳ mẫu nguồn đầy đủ nào, vì vậy ở đây tôi có thử nghiệm nhỏ nhất có thể đặt lại với nhau:

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

Trong tệp dự án hello-kitty.png của bạn, hãy truy cập src/test/resources. Trong kho lưu trữ thử nghiệm, nó được đóng gói vào thư mục /WEB-INF/classes trên classpath và do đó bạn có thể tải nó với cùng một trình nạp lớp mà thùng chứa được sử dụng cho kịch bản thử nghiệm của bạn.

IOUtils là từ apache commons-io.

Lưu ý bổ sung: Một điều mà tôi đã gãi đầu của tôi có liên quan đến khoảng trống trong đường dẫn đến máy chủ của tôi và cách getResourceAsStream() thoát như ký tự đặc biệt: sysLoader.getResource() problem in java

+0

Tại sao không sử dụng API Java 7 File? – BonanzaOne

Các vấn đề liên quan