จัดเก็บไว้ที่ใดก็ได้ในตำแหน่งที่สามารถเข้าถึงได้ยกเว้นโฟลเดอร์โครงการของ IDE หรือที่เรียกว่าโฟลเดอร์การปรับใช้ของเซิร์ฟเวอร์ด้วยเหตุผลที่ระบุไว้ในคำตอบสำหรับรูปภาพที่อัปโหลดจะมีให้หลังจากรีเฟรชหน้าเท่านั้น :
การเปลี่ยนแปลงในโฟลเดอร์โครงการของ IDE จะไม่ปรากฏในโฟลเดอร์งานของเซิร์ฟเวอร์ในทันที มีงานเบื้องหลังใน IDE ซึ่งดูแลว่าโฟลเดอร์งานของเซิร์ฟเวอร์ได้รับการซิงค์กับการอัปเดตล่าสุด (ซึ่งอยู่ในข้อกำหนด IDE เรียกว่า "การเผยแพร่") นี่คือสาเหตุหลักของปัญหาที่คุณพบ
ในรหัสโลกแห่งความเป็นจริงมีบางสถานการณ์ที่การจัดเก็บไฟล์ที่อัปโหลดไว้ในโฟลเดอร์ปรับใช้ของเว็บแอปจะใช้งานไม่ได้เลย เซิร์ฟเวอร์บางตัวทำ (โดยดีฟอลต์หรือตามคอนฟิกูเรชัน) ไม่ขยายไฟล์ WAR ที่ปรับใช้ไปยังระบบไฟล์โลคัลดิสก์ แต่จะอยู่ในหน่วยความจำทั้งหมดแทน คุณไม่สามารถสร้างไฟล์ใหม่ในหน่วยความจำได้โดยไม่ต้องแก้ไขไฟล์ WAR ที่ปรับใช้โดยพื้นฐานแล้วปรับใช้ใหม่
แม้ว่าเซิร์ฟเวอร์จะขยายไฟล์ WAR ที่ปรับใช้ไปยังระบบไฟล์ดิสก์ภายในเครื่องไฟล์ที่สร้างขึ้นใหม่ทั้งหมดจะสูญหายไปในการปรับใช้ใหม่หรือแม้แต่การรีสตาร์ทแบบธรรมดาเพียงเพราะไฟล์ใหม่เหล่านั้นไม่ได้เป็นส่วนหนึ่งของไฟล์ WAR ดั้งเดิม
จริงๆมันไม่สำคัญกับผมหรือคนอื่นที่ว่าในระบบไฟล์ดิสก์ภายในก็จะถูกบันทึกไว้ตราบใดที่คุณไม่ไม่เคยใช้getRealPath()
วิธีการ โดยใช้วิธีการที่อยู่ในใด ๆกรณีที่น่ากลัว
เส้นทางไปยังสถานที่จัดเก็บสามารถกำหนดได้หลายวิธี ที่คุณต้องทำทุกอย่างด้วยตัวเอง บางทีนี่อาจเป็นสาเหตุของความสับสนของคุณเนื่องจากคุณคาดว่าเซิร์ฟเวอร์จะดำเนินการทั้งหมดโดยอัตโนมัติ โปรดทราบว่า@MultipartConfig(location)
ไม่ได้ระบุปลายทางที่อัปโหลดสุดท้าย แต่สถานที่เก็บชั่วคราวสำหรับขนาดกรณีไฟล์เกินเกณฑ์เก็บความทรงจำ
ดังนั้นเส้นทางไปยังตำแหน่งจัดเก็บสุดท้ายสามารถกำหนดได้ด้วยวิธีใดวิธีหนึ่งดังต่อไปนี้:
hardcoded:
File uploads = new File("/path/to/uploads");
ตัวแปรสภาพแวดล้อมผ่านSET UPLOAD_LOCATION=/path/to/uploads
:
File uploads = new File(System.getenv("UPLOAD_LOCATION"));
อาร์กิวเมนต์ VM ระหว่างการเริ่มต้นเซิร์ฟเวอร์ผ่าน-Dupload.location="/path/to/uploads"
:
File uploads = new File(System.getProperty("upload.location"));
*.properties
รายการไฟล์เป็นupload.location=/path/to/uploads
:
File uploads = new File(properties.getProperty("upload.location"));
web.xml
<context-param>
ด้วยชื่อupload.location
และมูลค่า/path/to/uploads
:
File uploads = new File(getServletContext().getInitParameter("upload.location"));
ถ้ามีให้ใช้ตำแหน่งที่เซิร์ฟเวอร์จัดเตรียมไว้เช่นในJBoss AS / WildFly :
File uploads = new File(System.getProperty("jboss.server.data.dir"), "uploads");
ไม่ว่าจะด้วยวิธีใดคุณสามารถอ้างอิงและบันทึกไฟล์ได้อย่างง่ายดายดังนี้:
File file = new File(uploads, "somefilename.ext");
try (InputStream input = part.getInputStream()) {
Files.copy(input, file.toPath());
}
หรือเมื่อคุณต้องการสร้างชื่อไฟล์ที่ไม่ซ้ำกันโดยอัตโนมัติเพื่อป้องกันไม่ให้ผู้ใช้เขียนทับไฟล์ที่มีอยู่ด้วยชื่อเดียวกันโดยบังเอิญ:
File file = File.createTempFile("somefilename-", ".ext", uploads);
try (InputStream input = part.getInputStream()) {
Files.copy(input, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
วิธีการขอรับpart
ใน JSP / Servlet มีคำตอบในHow to upload files to server โดยใช้ JSP / Servlet? และวิธีการรับpart
ใน JSF มีคำตอบในHow to upload file โดยใช้ JSF 2.2 <h: inputFile>? ไฟล์ที่บันทึกไว้อยู่ที่ไหน
หมายเหตุ: ไม่ได้ใช้งานในขณะที่มันตีความเส้นทางเทียบกับที่ตั้งของการจัดเก็บชั่วคราวที่กำหนดไว้ในPart#write()
@MultipartConfig(location)
ดูสิ่งนี้ด้วย: