Đó là sự lựa chọn của bạn. Về cơ bản có ba cách trong kho lưu trữ ứng dụng web Java (WAR):
1. Đặt nó trong classpath
Vì vậy, bạn có thể tải nó bằng ClassLoader#getResourceAsStream()
một đường dẫn tương đối classpath:
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("foo.properties");
// ...
Properties properties = new Properties();
properties.load(input);
Ở đây foo.properties
được cho là được đặt trong một trong những gốc được bao phủ bởi đường dẫn lớp mặc định của ứng dụng web, ví dụ như ứng dụng web /WEB-INF/lib
và /WEB-INF/classes
, máy chủ /lib
hoặc JDK / JRE /lib
. Nếu thuộc tính là dành riêng cho webapp, tốt nhất là đặt nó vào /WEB-INF/classes
. Nếu bạn đang phát triển một dự án WAR tiêu chuẩn trong IDE, hãy thả nó vào src
thư mục (thư mục nguồn của dự án). Nếu bạn đang sử dụng dự án Maven, hãy thả nó vào /main/resources
thư mục.
Bạn cũng có thể đặt nó ở đâu đó bên ngoài đường dẫn mặc định và thêm đường dẫn của nó vào đường dẫn lớp của máy chủ ứng dụng. Trong ví dụ Tomcat, bạn có thể cấu hình nó làm shared.loader
tài sản của Tomcat/conf/catalina.properties
.
Nếu bạn đã đặt foo.properties
nó trong một cấu trúc gói Java như thế nào com.example
, thì bạn cần tải nó như dưới đây
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("com/example/foo.properties");
// ...
Lưu ý rằng đường dẫn này của trình nạp lớp ngữ cảnh không nên bắt đầu bằng a /
. Chỉ khi bạn đang sử dụng trình nạp lớp "tương đối" SomeClass.class.getClassLoader()
, thì bạn thực sự cần phải khởi động nó bằng a /
.
ClassLoader classLoader = getClass().getClassLoader();
InputStream input = classLoader.getResourceAsStream("/com/example/foo.properties");
// ...
Tuy nhiên, khả năng hiển thị của tệp thuộc tính sau đó phụ thuộc vào trình nạp lớp được đề cập. Nó chỉ hiển thị với trình nạp lớp giống như trình tải lớp. Vì vậy, nếu lớp được tải bởi vd, trình tải lớp chung của máy chủ thay vì trình tải lớp webapp và tệp thuộc tính nằm trong chính ứng dụng web, thì nó sẽ ẩn. Trình tải lớp ngữ cảnh là đặt cược an toàn nhất của bạn để bạn có thể đặt tệp thuộc tính "ở mọi nơi" trong đường dẫn lớp và / hoặc bạn dự định có thể ghi đè lên một máy chủ do webapp cung cấp.
2. Đặt nó trong liên kết web
Vì vậy, bạn có thể tải nó bằng ServletContext#getResourceAsStream()
một đường dẫn liên quan đến liên kết web:
InputStream input = getServletContext().getResourceAsStream("/WEB-INF/foo.properties");
// ...
Lưu ý rằng tôi đã chứng minh đặt tệp vào /WEB-INF
thư mục, nếu không nó sẽ được truy cập công khai bởi bất kỳ webbrowser nào. Cũng lưu ý rằng ServletContext
là trong bất kỳ HttpServlet
lớp chỉ truy xuất bởi di truyền GenericServlet#getServletContext()
và trong Filter
bằng FilterConfig#getServletContext()
. Trong trường hợp bạn không thuộc lớp servlet, nó thường chỉ được tiêm qua @Inject
.
3. Đặt nó trong hệ thống tập tin đĩa cục bộ
Để bạn có thể tải nó java.io
theo cách thông thường với đường dẫn hệ thống tệp đĩa cục bộ tuyệt đối:
InputStream input = new FileInputStream("/absolute/path/to/foo.properties");
// ...
Lưu ý tầm quan trọng của việc sử dụng một đường dẫn tuyệt đối. Đường dẫn hệ thống tệp đĩa cục bộ tương đối là không có trong ứng dụng web Java EE. Xem thêm liên kết "Xem thêm" đầu tiên bên dưới.
Chọn loại nào?
Chỉ cần cân nhắc những lợi thế / bất lợi theo quan điểm của riêng bạn về khả năng bảo trì.
Nếu các tệp thuộc tính là "tĩnh" và không bao giờ cần thay đổi trong thời gian chạy, thì bạn có thể giữ chúng trong WAR.
Nếu bạn muốn có thể chỉnh sửa các tệp thuộc tính từ bên ngoài ứng dụng web mà không cần phải xây dựng lại và triển khai lại WAR mỗi lần, sau đó đặt nó vào đường dẫn bên ngoài dự án (nếu cần thêm thư mục vào đường dẫn lớp).
Nếu bạn muốn có thể chỉnh sửa các tệp thuộc tính theo chương trình từ bên trong ứng dụng web bằng Properties#store()
phương pháp, hãy đặt nó bên ngoài ứng dụng web. Vì Properties#store()
yêu cầu a Writer
, bạn không thể sử dụng đường dẫn hệ thống tệp đĩa. Đường dẫn đó có thể lần lượt được chuyển đến ứng dụng web dưới dạng đối số VM hoặc thuộc tính hệ thống. Để phòng ngừa, không bao giờ sử dụnggetRealPath()
. Tất cả các thay đổi trong thư mục triển khai sẽ bị mất khi triển khai lại vì lý do đơn giản là các thay đổi không được phản ánh lại trong tệp WAR gốc.
Xem thêm: