2011-01-03 48 views
12

Tôi cần tải tệp thuộc tính từ bình. Bình được bao gồm trong tập tin chiến tranh. Dưới đây là cấu trúcCách tải tài nguyên từ tệp jar được đóng gói trong tệp chiến tranh?

ROOT.war 
    WEB-INF 
    lib 
     my.jar 

here my.jar has following structure 

my.jar 
    com 
    test 
     myservlet.class 
    WEB-INF 
    test.property 

Bây giờ tôi đã viết đoạn mã sau vào một trong servlet của tôi như sau:

InputStream stream = getServletContext().getResourceAsStream("/WEB-INF/test.properties"); 
Properties prop = new Properties(); 
prop.load(stream); 

nhưng trên mã tôi có dòng như null. Nếu tôi đặt các tập tin bất động sản trong ROOT.war/WEB-INF nó hoạt động tốt. Tôi có ý tưởng hợp lý rằng nếu đường dẫn trong getResourceAsStream bắt đầu bằng '/' hơn tài nguyên tìm kiếm trong thư mục gốc. Nhưng làm thế nào tôi có thể đọc tài nguyên nằm trong một cái bình mà lại tìm thấy trong WEB-INF/lib của ứng dụng gốc?

Cảm ơn & Kính trọng, Amit Patel

Trả lời

35

Đặt mã vào thư mục gốc của tệp JAR và nhận nó bằng trình nạp lớp ngữ cảnh thay cho servletcontext.

ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 
InputStream input = classLoader.getResourceAsStream("test.properties"); 
// ... 

Quy ước thư mục /WEB-INF dành riêng cho tệp WAR, không phải tệp JAR. Gạt nó ra. Nếu bạn thực sự cần một thư mục JAR riêng biệt là một phần của classpath, hãy sử dụng /META-INF để thay thế.

ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 
InputStream input = classLoader.getResourceAsStream("META-INF/test.properties"); 
// ... 
+0

... hoặc để nguyên mọi thứ như cũ và sử dụng "WEB-INF/test.property". –

+0

@bkail, cũng có thể, nhưng không có lý do gì để sử dụng thư mục 'WEB-INF' vì nó không bao giờ có thể truy cập được bởi servletcontext. Nó cũng không có ý nghĩa khi đặt một quy ước thư mục WAR cụ thể trong một tệp JAR vani thuần túy. – BalusC

+0

Đồng ý, không có nghĩa ngụ ý câu trả lời của bạn không chính xác. Chỉ cần cung cấp tùy chọn OP khác trong trường hợp thay đổi cấu trúc JAR là khó hoặc không thể vì một lý do nào đó. –

6

Bạn có thể truy cập vào bất kỳ tài nguyên trên classpath tiêu chuẩn từ một trường hợp cho

this.getClass().getResourceAsStream("name"); 

ví dụ từ lớp học của bạn "myservlet" (Bad đặt tên).

getServletContext().getResourceAsStream() truy cập nội dung trong ngữ cảnh của thư mục cơ sở ứng dụng web.

Có vẻ như phong cách xấu để phát sinh thư mục WEB-INF trong một cái bình - bạn sẽ gây nhầm lẫn. Bạn không thể tìm thấy một cái tên tốt hơn?

2

Đây là những gì tôi đã tìm thấy và nó phù hợp với tôi. Sự giúp đỡ được cung cấp bởi @BalusC đã làm việc cho tôi. Tôi đã đối chiếu những gì tôi đã tìm thấy và cách tôi đã xác minh rằng nó đang hoạt động.

Tôi đã có một dự án maven với cấu trúc sau như hình dưới đây

project structure

Bây giờ khi tôi xây dựng dự án này; jar trông giống như

enter image description here

và đây queries.properties di chuyển dưới thư mục "META-INF". Bây giờ nếu bình này có lớp đang cố gắng sử dụng tệp thuộc tính này bằng cách sử dụng Thread.currentThread().getContextClassLoader().getResourceAsStream("queries.properties")

nghĩ rằng cùng một tệp vẫn có thể được truy cập trong thư mục tài nguyên như được hiển thị trong cấu trúc dự án.Cách đúng là để truy cập thông qua thư mục META-INF

ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 
InputStream is = classLoader.getResourceAsStream("META-INF/queries.properties"); 

Làm thế nào đã làm tôi xác nhận

Chỉ cần tạo một dự án java đơn giản và bao gồm các jar mà bạn vừa tạo vào con đường xây dựng và tạo ra một thể hiện của lớp đang có các câu lệnh ClassLoader như đã đề cập ở trên. Mã của bạn trong dự án java mới này sẽ trông giống như

public static void main(String[] args){ 
     new Queries(); 
    } 

trong đó Queries là một lớp trong jar bạn vừa đưa vào đường dựng.

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