ฉันพบปัญหามากมายเมื่อใช้ Springboot เพื่ออัปโหลดไฟล์ ดังนั้นหลังจากอ่านโพสต์บล็อกจำนวนมากในที่สุดฉันก็ปรับปรุงฟังก์ชั่นการอัปโหลดตามนั้นดังนั้นฉันจึงบันทึกไว้ที่นี่เพื่อตรวจสอบในอนาคต
ก่อนอื่นเรากำลังสร้างโครงการสปริงบู๊ตมาตรฐาน IDE ที่ใช้ที่นี่เป็นแนวคิด Intellij สำหรับการกำหนดค่าที่ง่ายไฟล์การกำหนดค่าเริ่มต้นจะถูกแทนที่ด้วย application.yml
1. ฟังก์ชั่นการอัปโหลดไฟล์ดำเนินการใน index.html วิธีการอัปโหลดไฟล์ที่ใช้ที่นี่คือ AJAX แน่นอนคุณสามารถใช้ไฟล์แบบฟอร์มแบบดั้งเดิมเพื่ออัปโหลดตามข้อกำหนดเฉพาะของคุณ
<! doctype html> <html lang = "en"> <head> <meta charset = "utf-8"> <title> การทดสอบอัปโหลด </title> <script type = "text/javascript" src = "js/jQuery-3.2.1.min.js" <br/> <button id = "อัปโหลด" onclick = "doupload ()"> อัปโหลด </button> <progress id = "progressbar" value = "0" max = "100"> </progress> // js รับไฟล์ไฟล์ var fileController = "/upload"; // รับที่อยู่พื้นหลังของไฟล์ที่อัปโหลด // formData Object var Form = new FormData (); form.append ("ไฟล์", fileobj); // xmlhttprequest วัตถุ var xhr = ใหม่ xmlhttprequest (); // เพิ่มฟังก์ชั่นการประมวลผลแบบส่งคืน xhr.onreadyStateChange = function () {ถ้า (this.readyState == 4 && this.status == 200) {var b = this.responsetext; if (b == "ความสำเร็จ") {แจ้งเตือน ("อัปโหลดประสบความสำเร็จ!"); } else {แจ้งเตือน ("อัปโหลดล้มเหลว!"); - xhr.open ("โพสต์", filecontroller, true); // ใช้แถบความคืบหน้าเพื่อบันทึกความคืบหน้าการอัปโหลด xhr.upload.addeventListener ("ความคืบหน้า", progressfunction, false); xhr.send (แบบฟอร์ม); } ฟังก์ชั่น ProgressFunction (EVT) {var progressBar = document.getElementById ("progressBar"); var เปอร์เซ็นต์ = document.getElementById ("เปอร์เซ็นต์"); if (evt.lengthcomputable) {progressbar.max = evt.total; progressBar.Value = evt.loaded; PercentAghtiv.innerhtml = Math.Round (evt.loaded / evt.total * 100) + "%"; }} </script> </body> </html> 2. เพิ่มไฟล์อัปโหลด API ใน MainController และส่งคืนผลลัพธ์การอัปโหลด
@PostMapping ("/อัปโหลด") @ResponseBody สตริงสาธารณะอัปโหลด (คำขอ httpservletRequest, @requestparam ("ไฟล์") ไฟล์ multipartFile) {String path = "E: // upload //"; string filename = file.getoriginalfilename (); System.out.println (ชื่อไฟล์); ไฟล์ targetFile = ไฟล์ใหม่ (พา ธ ); if (! targetFile.exists ()) {targetFile.mkdirs (); } ไฟล์ saveFile = ไฟล์ใหม่ (พา ธ+ชื่อไฟล์); // บันทึกลอง {file.transferto (savefile); กลับ "ความสำเร็จ"; } catch (exception e) {e.printstacktrace (); กลับ "ล้มเหลว"; -ในเวลานี้เราทำการทดสอบและเราสามารถพบว่าการอัปโหลดไฟล์เสร็จสมบูรณ์แล้ว
หลายครั้งเมื่อเราอัปโหลดไฟล์โดยเฉพาะอย่างยิ่งเมื่อเปิดฟังก์ชั่นอัปโหลดไฟล์ไปยังผู้ใช้ทั่วไปเราจำเป็นต้องควบคุมรูปแบบของไฟล์ที่อัปโหลดเพื่อป้องกันไม่ให้แฮ็กเกอร์อัพโหลดสคริปต์ไวรัส วิธีการสกัดกั้นประเภทชื่อไฟล์นั้นง่ายมากที่จะแตก ผู้อัปโหลดจะต้องเปลี่ยนไวรัสเป็นชื่อไฟล์เพื่อทำการอัปโหลดให้เสร็จสิ้นเท่านั้น
ในเวลานี้เราสามารถอ่านส่วนหัวไฟล์ hexadecimal ของไฟล์เพื่อกำหนดรูปแบบที่แท้จริงของไฟล์
เนื่องจากเราพบว่าเมื่อเราอ่านข้อมูลไบนารีของไฟล์และแปลงเป็น hexadecimal ข้อมูลส่วนหัวไฟล์ของไฟล์ประเภทเดียวกันก็เหมือนกันและแม้ว่าคำต่อท้ายจะเปลี่ยนไปข้อมูลนี้จะไม่เปลี่ยนแปลง ตัวอย่างเช่นส่วนหัวไฟล์ของไฟล์ PNG คือ "89504E47"
ก่อนอื่นเราอ่านข้อมูลไฟล์
public class fileutil {สตริงคงที่สาธารณะ getFileHeader (ไฟล์ multipartFile) {inputStream คือ = null; ค่าสตริง = null; ลอง {is = file.getInputStream (); ไบต์ [] b = ไบต์ใหม่ [4]; IS.READ (B, 0, B.Length); ค่า = bytestohexstring (b); } catch (exception e) {} ในที่สุด {ถ้า (null! = is) {ลอง {is.close (); } catch (ioexception e) {}} ค่าส่งคืน; } สตริงคงที่ส่วนตัว bytestohexstring (byte [] src) {stringbuilder builder = new StringBuilder (); if (src == null || src.length <= 0) {return null; } สตริง HV; สำหรับ (int i = 0; i <src.length; i ++) {hv = integer.tohexstring (src [i] & 0xff) .touppercase (); if (hv.length () <2) {builder.append (0); } builder.append (HV); } system.out.println (builder.toString ()); return builder.toString (); -จากนั้นโทรออกในไฟล์ API ที่อัปโหลด
fileutil.getFileHeader (ไฟล์)
ในเวลานี้เราจำเป็นต้องทำการเปรียบเทียบสตริงอย่างง่ายและพิจารณาว่าค่าการส่งคืนของการโทรคือ "89504E47" และเราสามารถรู้ได้ว่าการอัปโหลดเป็นไฟล์ PNG หรือไม่
มาดู Java เพื่อรับและตัดสินข้อมูลส่วนหัวไฟล์
นำเข้า Java.io.FileInputStream; นำเข้า java.io.ioException; นำเข้า java.util.hashmap; / ** * รับและตัดสินข้อมูลส่วนหัวไฟล์ * * @author sud * */ คลาสสาธารณะ getTypebyhead {// ข้อมูลส่วนหัวไฟล์แคช - ข้อมูลส่วนหัวไฟล์สาธารณะคงที่สุดท้าย hashmap <สตริงสตริง> mfileTypes = new hashmap <สตริงสตริง> (); คงที่ {// images mfileTypes.put ("ffd8ff", "jpg"); mfileTypes.put ("89504E47", "PNG"); mfileTypes.put ("47494638", "GIF"); mfileTypes.put ("49492A00", "TIF"); mfileTypes.put ("424D", "BMP"); // mfileTypes.put ("41433130", "dwg"); // cad mfileTypes.put ("38425053", "PSD"); mfileTypes.put ("7B5C727466", "RTF"); // ไดอารี่ mfileTypes.put ("3C3F786D6C", "XML"); MFileTypes.put ("68746D6C3E", "HTML"); mfileTypes.put ("44656C697666572792D646174653A", "EML"); // อีเมล mfileTypes.put ("d0cf11e0", "doc"); mfileTypes.put ("5374616E64617264204A", "MDB"); MFileTypes.put ("252150532D41646F6265", "PS"); mfileTypes.put ("255444462D312E", "PDF"); mfileTypes.put ("504B0304", "DOCX"); mfileTypes.put ("52617221", "RAR"); mfileTypes.put ("57415645", "WAV"); mfileTypes.put ("41564920", "avi"); mfileTypes.put ("2E524D46", "RM"); mfileTypes.put ("000001BA", "MPG"); mfileTypes.put ("000001B3", "MPG"); mfileTypes.put ("6D6F6F76", "MOV"); mfileTypes.put ("3026B2758E66CF11", "ASF"); mfileTypes.put ("4D546864", "mid"); MFileTypes.put ("1F8B08", "GZ"); mfileTypes.put ("4D5A9000", "exe/dll"); mfileTypes.put ("75736167", "txt"); } / ** * รับข้อมูลส่วนหัวไฟล์ตามเส้นทางไฟล์ * * @param filepath * พา ธ ไฟล์ * @return ข้อมูลส่วนหัวไฟล์ * / สตริงคงที่สาธารณะ getFileType (สตริง filepath) {system.out.println System.out.println (mfileTypes.get (getFileHeader (filePath))); ส่งคืน mfileTypes.get (getFileHeader (filePath)); } / ** * รับข้อมูลส่วนหัวของไฟล์ตามเส้นทางไฟล์ * * @param filepath * พา ธ ไฟล์ * @return ข้อมูลส่วนหัวไฟล์ * / สตริงคงที่สาธารณะ getFileHeader (สตริง filePath) {fileInputStream คือ = null; ค่าสตริง = null; ลอง {is = new FileInputStream (FilePath); ไบต์ [] b = ไบต์ใหม่ [4]; / * * int read () อ่านไบต์ข้อมูลจากสตรีมอินพุตนี้ int read (byte [] b) อ่านถึงอาร์เรย์ไบต์ของข้อมูลของ b.length * ไบต์จากสตรีมอินพุตนี้ int read (byte [] b, int ปิด, int len) * อ่านข้อมูล len bytes ของข้อมูลจากสตรีมอินพุตนี้ลงในอาร์เรย์ไบต์ */ is.read (b, 0, b.length); ค่า = bytestohexstring (b); } catch (exception e) {} ในที่สุด {ถ้า (null! = is) {ลอง {is.close (); } catch (ioexception e) {}}} ค่าส่งคืน; } / ** * แปลงอาร์เรย์ไบต์ของไฟล์เพื่ออ่านข้อมูลส่วนหัวของไฟล์เป็นประเภทสตริงที่แสดงถึง * * @param src * อาร์เรย์ไบต์ของไฟล์เพื่ออ่านข้อมูลส่วนหัวของไฟล์ * @return ไฟล์ส่วนหัวไฟล์ * / สตริง Stringbuilder if (src == null || src.length <= 0) {return null; } สตริง HV; สำหรับ (int i = 0; i <src.length; i ++) {// ส่งคืนการแสดงสตริงของพารามิเตอร์จำนวนเต็มใน hexadecimal (ฐาน 16) จำนวนเต็มที่ไม่ได้ลงชื่อและแปลงเป็น uppercase hv = integer.tohexstring (src [i] & 0xff) if (hv.length () <2) {builder.append (0); } builder.append (HV); } system.out.println (builder.toString ()); return builder.toString (); } โมฆะคงที่สาธารณะหลัก (สตริง [] args) พ่นข้อยกเว้น {สตริงสุดท้าย fileType = getFileType ("d: //ry4s_java.dll"); System.out.println (fileType); -สรุป
ข้างต้นคือการควบคุมการอัปโหลดไฟล์ Springboot และข้อมูลส่วนหัวของไฟล์การตัดสิน Java และข้อมูลการตัดสินที่แนะนำให้คุณรู้จัก ฉันหวังว่ามันจะเป็นประโยชน์กับคุณ หากคุณมีคำถามใด ๆ โปรดฝากข้อความถึงฉันและบรรณาธิการจะตอบกลับคุณทันเวลา ขอบคุณมากสำหรับการสนับสนุนเว็บไซต์ Wulin.com!