มันเป็นทางเลือกของคุณ โดยทั่วไปมีสามวิธีในการเก็บถาวรแอปพลิเคชันเว็บ Java (WAR):
1. ใส่ไว้ใน classpath
เพื่อให้คุณสามารถโหลดโดยClassLoader#getResourceAsStream()
ใช้พา ธ พา ธ ที่สัมพันธ์กับคลาสพา ธ :
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("foo.properties");
// ...
Properties properties = new Properties();
properties.load(input);
นี่foo.properties
ควรจะถูกวางไว้ในหนึ่งของรากที่ได้รับความคุ้มครองโดย classpath เริ่มต้นของ webapp e กรัม webapp ของ/WEB-INF/lib
และ/WEB-INF/classes
เซิร์ฟเวอร์ของ/lib
หรือ /lib
JDK หาก propertiesfile เป็น webapp /WEB-INF/classes
เฉพาะที่ดีที่สุดคือการวางไว้ใน หากคุณกำลังพัฒนาโครงการสงครามมาตรฐานใน IDE ให้วางลงในsrc
โฟลเดอร์ (โฟลเดอร์ซอร์สของโครงการ) หากคุณกำลังใช้โครงการ Maven ให้วางไว้ใน/main/resources
โฟลเดอร์
คุณสามารถวางไว้ที่อื่นนอก classpath เริ่มต้นและเพิ่มเส้นทางไปยัง classpath ของ appserver ในตัวอย่าง Tomcat คุณสามารถกำหนดค่าเป็นทรัพย์สินของshared.loader
Tomcat/conf/catalina.properties
หากคุณวางไว้foo.properties
ในโครงสร้างแพ็คเกจ Java เช่นcom.example
นั้นคุณต้องโหลดดังต่อไปนี้
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("com/example/foo.properties");
// ...
/
โปรดทราบว่าเส้นทางของรถตักดินชั้นบริบทนี้ไม่ควรเริ่มต้นด้วย เฉพาะเมื่อคุณกำลังใช้ "ญาติ" กระบอกชั้นเช่นนั้นคุณแน่นอนจะต้องเริ่มต้นด้วยSomeClass.class.getClassLoader()
/
ClassLoader classLoader = getClass().getClassLoader();
InputStream input = classLoader.getResourceAsStream("/com/example/foo.properties");
// ...
อย่างไรก็ตามการมองเห็นของไฟล์คุณสมบัติจะขึ้นอยู่กับ class loader ที่เป็นปัญหา มันจะมองเห็นได้ในตัวโหลดคลาสเดียวกันกับตัวโหลดคลาส ดังนั้นหากโหลดคลาสโดยเซิร์ฟเวอร์เช่น classloader ทั่วไปแทน webapp classloader และไฟล์คุณสมบัติอยู่ใน webapp นั้นจะไม่สามารถมองเห็นได้ บริบทคลาสโหลดเดอร์เป็นเดิมพันที่ปลอดภัยที่สุดของคุณเพื่อให้คุณสามารถวางไฟล์คุณสมบัติ "ทุกที่" ใน classpath และ / หรือคุณตั้งใจจะสามารถแทนที่เซิร์ฟเวอร์ที่จัดหาให้จาก webapp บน
2. วางไว้ในเว็บคอนเทนต์
เพื่อให้คุณสามารถโหลดได้โดยServletContext#getResourceAsStream()
ใช้พา ธ ของเนื้อหาบนเว็บ:
InputStream input = getServletContext().getResourceAsStream("/WEB-INF/foo.properties");
// ...
โปรดทราบว่าฉันได้สาธิตการวางไฟล์ไว้ใน/WEB-INF
โฟลเดอร์ไม่เช่นนั้นเว็บเบราว์เซอร์ใด ๆ จะสามารถเข้าถึงได้แบบสาธารณะ นอกจากนี้ยังทราบว่าServletContext
เป็นในHttpServlet
ระดับที่สามารถเข้าถึงได้โดยการสืบทอดGenericServlet#getServletContext()
และโดยFilter
FilterConfig#getServletContext()
ในกรณีที่คุณไม่ได้อยู่ในคลาส servlet มักจะสามารถทำการฉีด@Inject
ได้
3. วางไว้ในระบบไฟล์ดิสก์ในเครื่อง
เพื่อให้คุณสามารถโหลดได้ตามปกติjava.io
ด้วยพา ธ ของระบบไฟล์ดิสก์ภายในระบบ:
InputStream input = new FileInputStream("/absolute/path/to/foo.properties");
// ...
จดบันทึกความสำคัญของการใช้พา ธ สัมบูรณ์ พา ธ ของระบบไฟล์ดิสก์โลคัลที่สัมพันธ์กันเป็นสิ่งที่ไม่ต้องทำอย่างแน่นอนในเว็บแอ็พพลิเคชัน Java EE ดูลิงค์แรก "เห็นด้วย" ด้านล่าง
เลือกแบบไหน?
เพียงชั่งน้ำหนักข้อดี / ข้อเสียในความเห็นของคุณในการบำรุงรักษา
หากไฟล์คุณสมบัติเป็น "คงที่" และไม่จำเป็นต้องเปลี่ยนแปลงระหว่างรันไทม์คุณสามารถเก็บไว้ในสงครามได้
หากคุณต้องการความสามารถในการแก้ไขไฟล์คุณสมบัติจากภายนอกเว็บแอ็พพลิเคชันโดยไม่จำเป็นต้องสร้างและปรับใช้ WAR อีกครั้งทุกครั้งให้วางไว้ใน classpath ภายนอกโครงการ (หากจำเป็นต้องเพิ่มไดเร็กทอรีไปยัง classpath)
หากคุณต้องการความสามารถในการแก้ไขไฟล์คุณสมบัติโดยทางโปรแกรมจากภายในเว็บแอ็พพลิเคชันโดยใช้Properties#store()
เมธอดวางไว้ด้านนอกเว็บแอ็พพลิเคชัน ตามที่Properties#store()
ต้องการWriter
คุณจึงไม่สามารถไปไหนได้โดยใช้พา ธ ของระบบไฟล์ดิสก์ สามารถส่งผ่านพา ธ นั้นไปยังเว็บแอ็พพลิเคชันเป็นอาร์กิวเมนต์ VM หรือคุณสมบัติระบบ เพื่อเป็นการป้องกัน, ไม่เคยgetRealPath()
ใช้ การเปลี่ยนแปลงทั้งหมดในโฟลเดอร์การนำไปใช้งานจะสูญหายไปใน redeploy ด้วยเหตุผลง่ายๆว่าการเปลี่ยนแปลงจะไม่สะท้อนกลับมาในไฟล์ WAR ดั้งเดิม
ดูสิ่งนี้ด้วย: