في الآونة الأخيرة ، سألني زميلي عما إذا كان لدي أي كتب إلكترونية عن التكنولوجيا. لقد فتحت المكتبة الصغيرة على جهاز الكمبيوتر الخاص بي ، لكن البريد الإلكتروني كان كبيرًا جدًا لإرساله ، وحظرت الشركة المشاركة مع المجلدات ، لذلك قضيت نصف يوم في كتابة برنامج تحميل ملفات صغير ونشره على جهاز Linux الخاص بي.
توفير الوظائف: 1. تحميل الملف 2. عرض قائمة الملفات وتنزيله
القطعة الأصلية التي تم تحميلها هي قبيحة. كتبت بعض كود JS لتحسينه. تظهر الواجهة النهائية على النحو التالي:
أولا إعطاء النتائج ، وأسفل سيوضح كيفية تنفيذها خطوة بخطوة.
1. إنشاء مشروع جديد
أول شيء هو إنشاء مشروع جديد للبوت الربيع. يمكنك اختيار تهيئة مشروع على موقع الويب أو استخدام وظيفة Spring Eirlier لـ IDE ، ويمكنك إنشاء مشروع جديد. هنا أقوم بإنشاء مشروع جديد من IDEA:
بعد ذلك ، ثم أدخل المجموعة والقطع الأثرية واستمر في النقر بعد ذلك:
في هذا الوقت ، تظهر واجهة اختيار الوحدة هذه. انقر فوق خيار الويب وتحقق من الويب لإثبات أن هذا هو webapp. ثم انقر فوق محركات القالب لتحديد محرك القالب الأمامي. نختار ثيميلف. يوصي مسؤول Spring-Boot أيضًا باستخدام هذا القالب بدلاً من JSP.
الخطوة الأخيرة ، ثم انتظر تهيئة المشروع بنجاح.
2. إعدادات POM
أولاً ، تحقق من التبعيات التي تحتاج إلى إضافتها إلى المشروع ونشر ملف POM الخاص بي مباشرة:
<؟ XSI: schemalocation = "http://maven.apache.org/pom/4.0.0 <soph> 0.0.1-snapshot </version> <packaging> جرة </packaging> <name> التحميل </name> <speciped> مشروع تجريبي لـ Spring Boot </description> <parent> <roupiD> org.springframework.boot </rowisted> <!-Lookup Parent from ropository-> </paret> <properties> <project.build.sourceencoding> utf-8 </project.build.sourceencoding> <project.reporting.outputencoding> utf-8 </project.reporting.utputencoding> <ependencies> <Rependency> <roupiD> org.springframework.boot </rougiD> <StifactId> spring-boot-starter </shintifactid> </sependency> <preemndency> <roupiD> org.springframework.boot </rougeid> <roughid> org.springframework.boot </rougiD> <StifactId> Spring-boot-configuration-processor </shintifactid> <peciptional> true </prectiD> </redenced> <redency> <roupend> org.springframework.boot </rougeid> <scope> اختبار </scope> </sependency> <!-https://mvnrepository.com/artifact/org.webjars/bootstrap-> <redexid> <roupiD> org.webjars </rougiD> https://mvnrepository.com/artifact/org.webjars.bower/jquery -> <reperency> <roupeD> org.webjars.bower </groupId> <stifactid> jquery </shifactid> <roupringid> org.springframework.boot </rougiD> <StifactId> Spring-boot-maven-plugin </stifactid> </spliexin> </sultiins> </build> </project>
يمكنك أن ترى أن Spring-Boot-Starter-Thymeleaf يحتوي على WebApp ، وسيتم استخدام آخر اثنين من webjars bootstrap و jQuery ، وسيتم استخدام الرموز الأخرى.
تتم إضافة المكون الإضافي في Spring Boot Maven عند إنشاء النظام ، ولديه الفوائد التالية:
1. يمكنه حزم جميع الجرار تحت ClassPath وإنشاء "über-Jar" قابل للتنفيذ لتسهيل المستخدمين إلى نقل الخدمات.
2. ابحث تلقائيًا عن طريقة الفراغ الثابتة العامة () وتمييزها كصف قابل للتنفيذ
3. وفقًا لإصدار Spring-Boot ، يتم توفير تفسير تبعية مدمج.
3. تحميل وحدة تحكم الملف
إذا كنت تستخدم فقط springMVC لتحميل الملفات ، فأنت بحاجة إلى تكوين حبة متعددة الأدوات ، أو تكوين <multipart-config> في web.xml ، ولكن بمساعدة التكوين التلقائي لـ Spring-Boot ، لا يتعين عليك فعل أي شيء. لكتابة فئة وحدة التحكم مباشرة ، نقوم بإنشاء حزمة وحدة تحكم جديدة ضمن SRC/Main/Java وننشئ FileUploAdController جديد:
package com.shuqing28.upload.controller ؛ استيراد com.shuqing28.uploadfiles.pojo.linker ؛ استيراد com.shuqing28.uploadfiles.exceptions.storagefilenotfoundexception ؛ import com.shuqing28.uploadfiles.service.storageservice ؛ org.springframework.beans.factory.annotation. org.springframework.ui.model ؛ استيراد org.springframework.web.bind.annotation.*؛ استيراد org.springframework.web.multipart.multipartfile org.springframework.web.servlet.mvc.support.redirectattributes ؛ import java.ioexception ؛ import java.util.list ؛ firm java.util.stream.collectors ؛ controllerpublicpublicpublicpublicpubluadcontroller @autowired pileuploadController (Storageservice Storageservice) {this.storageservice = storageservice ؛ } getMapping ("/") السلسلة العامة listUploadedFiles (نموذج النموذج) يلقي ioException {list <Linker> linkers = storageservice.loadall (). map (path -> new Linker (mvCuricomponentsBuilder.frommethodName (fileuploadcontroller.class ، path.getFilename (). toString ()). build (). Model.AdDattribute ("Linkers" ، Linkers) ؛ إرجاع "تحميل" ؛ } getMapping ("/files/{filename:.+}") responsebody public reponseentity <srodust> servile (اسم ملف السلسلة pathvariable) {resource file = storageservice.loadasresource (filename) ؛ Return Responseentity.ok (). header (httpheaders.content_disposition ، "المرفق ؛ filename =/" " + file.getFilename () +" /"").body(file) ؛ } postmapping ("/") سلسلة public fallfileUpload ( @requestparam ("file") ملف multipartfile ، إعادة توجيه redirectattributes) {storageservice.store (file) ؛ redirectattributes.addflashattribute ("message" ، "تم تحميلك بنجاح" + file.getoriginalfilename () + "!") ؛ إرجاع "إعادة التوجيه:/" ؛ } exceptionHandler (storagefilenotfoundException.class) الاستجابة العامة <؟> handlestoragefilenotfound (StorageFilenotFoundException Exc) {return receptionentity.notfound (). build () ؛ }}تتم إضافة شرح Controller في تعريف الفصل ، مما يثبت أن هذا هو وحدة تحكم. تتم إضافة كل طريقة باستخدام GetMapping و postmapping المقابلة لطلبات الحصول على و Post على التوالي.
بادئ ذي بدء ، يعرض GetMapping ("/") ، Method ListUploadedFiles ، كما يوحي الاسم ، قائمة الملفات. نحن هنا نستخدم Storageservice لاجتياز جميع الملفات في المجلد ، ونستخدم طريقة الخريطة لتجميع قائمة الرابط وأسماء الملف ، وإرجاع مجموعة من كائنات الرابط. كائن الرابط هو pojo بسيط ، والذي يحتوي فقط على الجزأين التاليين:
سلسلة خاصة fileurl ؛ اسم ملف السلسلة الخاص ؛
تتضمن هذه الطريقة استخدام الدفق في Java8. إذا كنت لا تفهم ، يمكنك قراءة هذه المقالة حول ميزات Java8 بالتفصيل (II) API.
التالي هو @GetMapping("/files/{filename:.+}") ، وهو Servile ، والذي يوفر وظيفة تنزيل الملف ، أو يستخدم Storageservice ، وسيتم نشر رمز Storageservice لاحقًا. أخيرًا ، استخدم الاستجابة لإرجاع الملف كهيئة إلى الطرف طلب.
يستخدم HandlefileUpload من @PostMapping("/") طلب النشر لتحميل الملفات. يقوم المعلمة @REQUESTPARAM ("ملف") باستخراج كائن الملف في طلب صفحة الويب ، أو يستخدم Storageservice لحفظ الكائن ، ويستخدم أخيرًا إعادة توجيه لتحديث صفحة الويب ، ويعطي الرسالة التي تم تحميلها بنجاح.
4. معالجة الملفات
يتم توفير العديد من الطرق التي يطلق عليها وحدة التحكم أعلاه بواسطة Storageservice. نحدد واجهة تحتوي على الطرق التالية:
package com.shuqing28.uploadfiles.service ؛ استيراد org.springframework.core.io.resource ؛ استيراد org.springframework.web.multipart.multipartfile ؛ استيراد java.file.file.path ؛ Void Store (ملف multipartfile) ؛ دفق <PATH> LOADALL () ؛ تحميل المسار (اسم ملف السلسلة) ؛ موارد loadasResource (اسم ملف السلسلة) ؛ void deleteall () ؛}
لأنني فقط أستخدم نظام الملفات المحلي لمعالجة التنزيلات طويلة الأجل للملفات ، لدي فئة التنفيذ التالية:
package com.shuqing28.uploadfiles.service ؛ استيراد com.shuqing28.uploadfiles.exceptions.storageException ؛ استيراد com.shuqing28.uploadfiles.exceptions.storagefilenotfoundexception ؛ org.springframework.beans.factory.annotation.autowired ؛ استيراد org.springframework.core.io.resource org.springframework.util.StringUtils ؛ استيراد org.springframework.web.multipart.multipartfile ؛ استيراد java.io.ioException ؛ import java.net.malformedurlexception ؛ import java.nio.file.files ؛ import java.file ؛ java.nio.file.paths ؛ استيراد java.nio.file.StandardCopyOption ؛ استيراد java.util.stream.stream ؛ servicepublic class fileystemstorageservice storageservice @autowired publicystemstorageservice (خصائص storageProperties) {this.rootlocation = paths.get (properties.getLocation ()) ؛ } Override public void init () {try {files.createdIrectories (rootlocation) ؛ } catch (ioException e) {رمي storageException جديد ("لا يمكن تهيئة التخزين" ، e) ؛ }} Override public void Store (file multipartfile) {String filename = stringUtils.cleanPath (file.getoriginalfilename ()) ؛ حاول {if (file.isempty ()) {رمي التخزين الجديد ("فشل في تخزين ملف فارغ" + اسم ملف) ؛ } if (filename.contains ("..")) {// هذا هو فحص أمني رمي تخزين جديد ("لا يمكن تخزين الملف مع المسار النسبي خارج الدليل الحالي" + اسم fileName) ؛ } files.copy (file.getInputStream () ، this.rootlocation.resolve (filename) ، standardcopyoption.replace_existing) ؛ } catch (ioException e) {رمي storageException جديد ("فشل في تخزين الملف" + اسم الملف ، e) ؛ }} Override Public Stream <That> loadall () {try {return files.walk (this.rootlocation ، 1) .filter (path ->! path.equals (this.rootlocation)) .map (path-> this.rootlocation.Releativize (path)) ؛ } catch (ioException e) {رمي التخزين الجديد ("فشل في قراءة الملفات المخزنة" ، e) ؛ }} Override Public Path Load (اسم ملف السلسلة) {return rootlocation.Resolve (filename) ؛ } Override Public Resource LoadAsResource (اسم ملف السلسلة) {try {path file = load (filename) ؛ مورد المورد = urlresource الجديد (file.touri ()) ؛ if (Resource.exists () || Resource.isReadable ()) {return Resource ؛ } آخر {رمي storagefilenotfoundException ("لا يمكن قراءة الملف:" + filename) ؛ }} catch (malformedurlexception e) {رمي storagefilenotfoundException ("لا يمكن قراءة الملف:" + اسم الملف ، e) ؛ }} Override public void deleteall () {fileSystemUtils.DeLeterCursivaly (rootlocation.tofile ()) ؛ }}يستخدم هذا الفئة أيضًا بشكل أساسي NIO من Java ، ويستخدم كائن المسار لتحديد مسار حفظ الافتراضي لموقع الملف.
دعونا نلقي نظرة على طريقة المتجر أولاً. يقبل المتجر كائن متعدد الأطوار كمعلمة. بالمقارنة مع JSP التقليدية ، فإنه يمر فقط صفائف بايت ثنائية. يوفر MultipartFile العديد من الطرق المريحة للاتصال ، حتى نتمكن من الحصول على معلومات مختلفة حول الملف الذي تم تحميله:
الواجهة العامة multipartfile يمتد inputStreamSource {string getName () ؛ سلسلة getoriginalfilename () ؛ سلسلة getContentType () ؛ منطقية isempty () ؛ GetTize () طويلة ؛ بايت [] getBytes () يلقي ioException ؛ inputStream getInputStream () يلقي ioException ؛ نقل باطل (مصير الملف) يلقي ioException ، غير unalfalStateException ؛} يستخدم الرمز طريقة نسخ الملفات لنسخ دفق الملف إلى المسار المقابل للموقع. بالطبع ، يمكننا أيضًا استخدام طريقة Transferto لحفظ الملف ، file.transferTo(this.rootLocation.resolve(filename).toFile());
تقوم طريقة Loadall بتحميل جميع معلومات مسار الملف في هذا المسار ، تقوم LoadAsResource بتحميل الملف ككائن مورد ، ثم انظر إلى رمز وحدة التحكم ، ويقبل أخيرًا كائن مورد كهيئة للعودة إلى الطالب.
5. قالب الواجهة الأمامية
أخيرًا ، يتم تعريف القالب الأمامي ، وهنا سنظل ننظر إلى الكود أولاً:
<html xmlns: th = "http://www.thymeleaf.org"> <head> <title> مشاركة الملفات </title> </head> <body> <div th: if = "$ {message}"> <h2 th: text = "$ {message}" enctype = "multipart/form-data"> <!-start component-> <input type = "file" name = "file" style = "الرؤية: Hidden ؛ الارتفاع: 0"/> <div> <div name = "fichier1"> <input type = "text" text "placeholder = '/'/> <span> -> <div> <button type = "submit"> إرسال </button> <button type = "reset"> إعادة تعيين </button> </fire> </form> </viv> <viv> <ul> <li th: كل = "linker: $ {linkers}"> <a th: href = "$ {linker.fileurl} TH: text = "$ {linker.filename}"/> </li></ul> </viv> <script src = "// ajax.aspnetcdn.com/ajax/jquery/jquery-1.9.1.min.js"></script><script> src = "/webjars/bootstrap/3.3.5/js/bootstrap.min.js"> </script> <script type = "text/javaScript" th: inline = "javaScript"> function bs_input_file () {$ (". $ (this) .prev (). hasclass ('input-ghost')) {var element = $ (". input-ghost") ؛ $ (this) .find ("button.btn-choose"). انقر فوق () {element.click () ؛}) ؛ $ (هذا). } $ (function () {bs_input_file () ؛}) ؛ </script> <link Rel = "STYLESHEET" href = "/webjars/bootstrap/3.3.5/css/bootstrap.min.css" rel = "الخارجي nofollow"/> </body> </html>الشيء المهم هنا هو المحتوى في علامة <Porm>. <method method = "post" Action = "/" enctype = "multipart/form-data"> يجب كتابة enctype على أنها multipart/form-data. استخدم post لتحميل الملفات. عنصر تحكم التحميل الأصلي قبيح ، لذلك قمت بإدخال نص+ووضعه على السطح ، ووضعت إدخال ملف التحميل غير المرئي أدناه. يمكنك إلقاء نظرة على الكود بنفسك ، لذلك لن أتحدث عن ذلك في هذه المقالة.
هنا نضع أيضًا قائمة لعرض قائمة الملفات. هنا نحصل على كائن الروابط المقدمة من الخادم. بواسطة Foreach باستمرار ، يمكننا الحصول على العنصرين في Fileurl و Filename.
هنا ، تم استبدال jQuery بـ CDN من Microsoft ، ولا يمكن تقديم WebJars ، لذلك لا أعرف السبب.
إعدادات أخرى
اضبط حد حجم ملف التحميل في SRC/Main/Resources/Application.Properties
spring.http.multipart.max-file-size = 128mbspring.http.multipart.max-request-size = 128mb
بالإضافة إلى ذلك ، يتم تعيين مسار حفظ الملف الافتراضي أيضًا:
package com.shuqing28.uploadfiles.config ؛ استيراد org.springframework.boot.context.properties.ConfigurationProperties ؛@configurationProperties ("التخزين") تخزين الطبقة العامة {موقع السلسلة الخاصة/"/jenkins/exploadiples/" ؛ السلسلة العامة getLocation () {return location ؛ } public void setLocation (موقع السلسلة) {this.location = location ؛ }}لاحظ هنا أنه نظرًا لإعداد StorageProperties ، تحتاج إلى إضافته إلى فئة التطبيق.
enableConfigurationProperties annotation@springbootapplication@enableConfigurationProperties (StorageProperties.class) تحميل الفئة العامة {public static void main (string [] args) {springapplication.run (uploadapplication.class ، args) ؛ }}لخص
ما سبق هو SPRING BOOT + THYMELEAF الذي قدمه لك المحرر لتحقيق وظيفة تحميل الملف وتنزيله. آمل أن يكون ذلك مفيدًا لك. إذا كان لديك أي أسئلة ، فيرجى ترك رسالة لي وسوف يرد المحرر إليك في الوقت المناسب. شكرا جزيلا لدعمكم لموقع wulin.com!