1. نظرة عامة على الدورة
في تطوير نظام تطبيق الويب ، تعد وظيفة تحميل الملفات وظيفة شائعة جدًا. اليوم ، دعونا نتحدث بشكل أساسي عن التنفيذ الفني ذي الصلة لوظيفة تحميل الملفات في Javaweb. مع التطوير السريع لتكنولوجيا الإنترنت ، تزداد متطلبات تجربة المستخدمين لمواقع الويب. هناك أيضًا العديد من النقاط المبتكرة في تكنولوجيا وظيفة تحميل الملفات ، مثل التحميل غير المتزامن ، وتحميل السحب والإفلات ، وتحميل اللصق ، ومراقبة التقدم ، وملفات الملفات المصغرة ، وإرسال نقطة توقف كبيرة في ملف ، ونقل فوري ملف كبير ، إلخ.
الأساسيات المطلوبة لهذه الدورة:
فهم محتوى بروتوكول HTTP الأساسي
تقنية تشغيل دفق IO الأساسية
أساسيات servlet
المعرفة الأساسية لتكنولوجيا JavaScript/jQuery
2. أساسيات تحميل الملف
لتحميل الملف ، يقدم المتصفح الملف إلى جانب الخادم في شكل دفق أثناء عملية التحميل ، وسيتم نقل جميع بيانات البث إلى جانب الخادم مع طلب HTTP. لذلك ، يجب فهم تنسيق المحتوى المطلوب عند تحميل الملف بشكل أساسي.
صفحة تحميل الملف:
<form action = "/itheimaupload/uploadservlet" method = "post" enctype = "multipart/form-data"> الرجاء تحديد الملف المحمّل: <input type = "file" name = "attach"/> <br/> <input type = "falle"
محتوى طلب HTTP:
3. خلفية Java تستخدم Servlet لتلقي الملفات
من المزعج إذا كنت تستخدم Servlet للحصول على دفق الإدخال من الملفات التي تم تحميلها ثم تحليل معلمات الطلب فيه. لذلك ، عمومًا ، تختار الخلفية استخدام مكون تحميل ملف المشترك المشترك ، وهو أداة المصدر المفتوح لـ Apache.
. تكوين Cache DiskfileItemFactory Factory = New DiskfileItemFactory (1*1024*1024 ، ملف جديد ("C:/tempfiles/")) ؛ // 2. إنشاء servleFilePload Object servletFilePload Sfu = new ServleTfileUpload (المصنع) ؛ // حل المشكلة الصينية لاسم الملف sfu.setheaderencoding ("UTF-8") ؛ // 3. حل Try {list <IbleItem> list = sfu.parserequest (request) ؛ // حل جميع المحتوى إذا (list! = null) {for (pileItem ite: list) {// حدد ما إذا كان معلمة نموذجية عادية (item.isformfield ()) {// معلمات النموذج العادية // احصل value = item.getString ("UTF-8") ؛ } else {// file if (item.getName ()! = null &&! item.getName (). يساوي ("")) {// حفظ إلى خادم القرص الثابت fileutils.copyinputStreamTileTofile (item.getInputStream () ، ملف جديد ("c:/targetfiles/" item.getname ()) ؛ (FileUploAdexception e) {E.PrintStackTrace () ؛}} public void dopost (طلب httpservletrequest ، استجابة httpservletrespons4. استخدم WebUploader لتحميل المكونات
في الطرف الأمامي من صفحة تحميل الملف ، يمكننا اختيار استخدام بعض مكونات التحميل الأكثر فائدة ، مثل WebUploader المكون المفتوح من Baidu. يمكن لهذا المكون أن يفي بشكل أساسي ببعض الوظائف اليومية لتحميل الملفات ، مثل التحميل غير المتزامن ، وتحميل السحب والإفلات ، ولصق التحميل ، ومراقبة التقدم ، وملفات الملفات ، وحتى نقاط توقف الملفات الكبيرة لمتابعة الإرسال ، ونقل الملفات الكبيرة بالثواني.
قم بتنزيل مكون WebUpload
http://fex.baidu.com/webuploader/ قم بتنزيل حزمة webupload على موقع الويب الرسمي على webupload
هيكل دليل WebUpload:
توضيح تحميل الملف الأساسي (بما في ذلك التحميل المحرز)
الواجهة الأمامية
1.1 استيراد CSS المطلوبة ، JS على الصفحة
<link rel = "stylesheet" type = "text/css" href = "$ {pagecontext.request.contextpath} /css/webuploader.css } /js/jquery-1.10.2.min.js "> </script> <script type =" text/javaScript "src =" $ {pagecontext.request.contextpath} /js/webuploader.js1.2 اكتب علامة صفحة التحميل
<!-تحميل div-> <div id = "uploader"> <!-معلومات قائمة الملفات-> <ul id = "fileList"> </ul> <!-حدد منطقة الملف-> <div id = "filepicker"> انقر لتحديد الملف </div> </viv>
1.3 كتابة رمز التحميل webupload
<script type = "text/javaScript"> // 1. تهيئة webupload وتكوين المعلمات العالمية var uploader = webuploader.create ({// flashk control address swf: "$ {pagecontext.request.contextpath} /js/uploader.swf" ، // backend srited server: "$ {pagecontext.request.context. اختيار علامة التحكم: "#filepicker" ، // ملف التحميل التلقائي التلقائي: TRUE ،}) ؛ // 2. بعد تحديد الملف ، عرض قائمة انتظار معلومات الملف // قم بتسجيل الحدث filequeued: يتم تشغيله عند إضافة الملف إلى قائمة الانتظار // ملف: يمثل تحميل الملف المحدد حاليًا ("filequeued" ، الدالة (ملف) {// إضافة معلومات الملف div $ ("#fileList"). class = 'fileInfo'> <span> "+file.name+" </span> <div class = 'state'> في انتظار التحميل ... </div> <span class = 'text'> </span> </viv> ") ؛}) ؛ // 3. سجل تحميل التقدم المحرز/الملف: تحميل ملف // النسبة المئوية: نسبة التقدم الحالي. الحد الأقصى هو 1. على سبيل المثال: 0.2uploader.on ("UploadProgress" ، الوظيفة (الملف ، النسبة المئوية) {var id = $ ("#" id.find ("span.text"). النص (Math.Round (النسبة المئوية*100)+"٪") ؛}) ؛ // 4. تسجيل وتحميل الاستماع//ملف: ملف تم تحميله // الاستجابة: البيانات التي تم إرجاعها بواسطة الخلفية ، إرجاع تحميل.2) رمز الخدمة الخلفية
مصنع diskfileItemFactory = جديد diskfileItemFactory () ؛ servletfileUpload sfu = new servletfileupload (factory) ؛ sfu.setheaderencoding ("utf-8") ؛ جرب {list <ibuitem> عناصر = sfu.parserequest (request) ؛ العنصر: العناصر) {if (item.isformfield ()) {// معلومات عادية} آخر {// معلومات الملف // الحكم على أنه يجب حفظ الملفات فقط ومعالجتها. file (serverpath+"/"+item.getName ())) ؛ system.out.println ("ملف ينقذ بنجاح") ؛}}} catch (fileUploadexception e) {eprintstacktrace () ؛}توليد الصورة المصغرة
النقطة الرئيسية: طريقة تحميل المكالمات. makethumb ()
uploader.on ("filequeued" ، function (file) {// إلحاق معلومات الملف div $ ("#fileList"). class = 'text'> </span> </viv> ") ؛ // اصنع صورة مصمارية للصور: اتصل بـ makethumb () method // error: فشل في إنشاء thumbnails // src: مسار thumbnails uploader.makethumb (ملف ، وظيفة (خطأ ، src) {var id = $ ("#" إذا كان (خطأ) {id.find ("img"). replacewith ("لا يمكن معاينة") ؛} // إذا نجحت ، فسيتم عرض الصورة المصغرة على معرف الموضع المحدد ("img"). attr ("src" ، src) ؛سحب ولصق وتحميل
1) أضف div إلى منطقة السحب على الصفحة
<!-تحميل div-> <div id = "uploader"> <!-منطقة سحب الملف-> <div id = "dndarea"> <p> اسحب الملف مباشرة هنا للتحميل تلقائيًا </p> </viv> <!
2) أضف معلمات السحب والإفلات إلى معلمات التكوين العالمية لـ WebUploader
// 1. تهيئة webupload وتكوين المعلمات العالمية var uploader = webuploader.create ({// flashk control address swf: "$ {pagecontext.request.contextpath} /js/uploader.swf" ، // backend srited server: "$ {pagecontext.request.context. اختيار علامة التحكم: "#filepicker" ، // endload file auto: true ، // تمكين وظيفة السحب والإفلات ، حدد منطقة السحب DND: "#dndarea" ، // تعطيل وظيفة السحب والإسقاط في أماكن أخرى من الصفحة لمنع الصفحة مباشرة من فتح الملف disableglobaldnd: true // تمكين peste: "#exploader"}) ؛تحميل ملفات كبيرة في قطع
1) أضف معلمات تحميل الكتلة إلى المعلمات العالمية لـ WebUploader
// 1. تهيئة webupload وتكوين المعلمات العالمية var uploader = webuploader.create ({// flashk control address swf: "$ {pagecontext.request.contextpath} /js/uploader.swf" ، // backend srited server: "$ {pagecontext.request.context. اختيار علامة التحكم: "#filepicker" ، // تحميل تلقائي تلقائيًا: TRUE ، // تمكين وظيفة السحب والإفلات ، حدد منطقة السحب DND: "#dndarea" ، // تعطيل وظيفة السحب والإسقاط في أماكن أخرى لمنع الصفحة من فتح الملف بشكل مباشر: chunked: true ، // حجم الملف لكل كتلة (افتراضي 5M) chunksize: 5*1024*1024 ، // افتح عدة مؤشرات ترابط متزامنة (افتراضي 3) مؤشرات الترابط: 3 ، // عند تحميل الملف الحالي ، preparenextFile: True}) ؛2) مراقبة ثلاث نقاط زمنية لتحميل الملفات
بعد إضافة التكوينات الثلاثة أعلاه ، ستجد أنه عندما يتجاوز الملف 5 أمتار ، فإن WebUploader سترسل الملف تلقائيًا إلى الخلفية.
يحتوي كل طلب كتلة على معلومات:
يمكنك الاستماع إلى ثلاث نقاط زمنية مهمة في عمليات تحميل الملفات في قطع.
قبل الملف: اتصل مسبقًا قبل تقديمه: إذا كانت هناك كتل ، اتصل برفع ما بعد الإقامة قبل إرسال كل كتلة: يتم استدعاءها بعد إرسال جميع الكتل // 5. راقب النقاط الزمنية الثلاث لتحميل الملف (ملاحظة: يجب وضع هذا القسم من الكود قبل webuploader.create) // الوقت النقطة 1 :: قبل تحميل جميع الكتل (1. يمكن حساب العلامة الفريدة للملف ؛ 2 يمكن أن تحدد ما إذا كان قد تم نقله في الثواني) // ناقل الحركة المستمر نقطة الإيقاف) // الخطوة 3: بعد كل أجزاء يتم تحميلها بنجاح (1. إخطار خلفية ملفات القطع لدمجها) webuploader.uploader.register ({"قبل الانتعاش": "beordesendfile" ، "قبل الانتعاش": "Be Beatheresend" ، "بعد الانتعاش": " التحميل في جميع الأجزاء Be Formoresendfi LE: Function () {// 1. طلب ما إذا كانت الخلفية قد حفظت الكتلة الحالية. في حالة وجوده ، تخطي ملف الكتلة لإدراك وظيفة الإرسال المستمر في نقطة الإيقاف} ، // الخطوة 3: استدعاء هذه الوظيفة بعد تحميل جميع الكتل بنجاح بعد SendFile: function () {// 1. إذا تم تحميله في كتل ، يتم دمج جميع ملفات الحظر من خلال الخلفية}}) ؛منطق ملف قبل الانتعاش:
// استخدم طريقة md5file () لحساب العلامة الفريدة للملف // هذه الوظيفة تتلقى مؤلفًا من forsendfile: function (file) {// إنشاء مؤلف مؤلف = webuploader.deferred () ؛ // 1. احسب العلامة الفريدة للملف ، المستخدمة في الإرسال المستمر في نقطة الإيقاف والإرسال الثاني (webuploader.uploader ()). تم الاسترجاع ... ") ؛}). اطلب ما إذا كانت الخلفية قد حفظت الملف. إذا كان موجودًا ، فسيتم تخطي الملف لتحقيق وظيفة المرور الثانية // الإرجاع المؤلف. promise () ؛}المنطق قبل الالتقاط:
// أرسل علامة فريدة من الملف الحالي إلى الخلفية ، والتي يتم استخدامها لإنشاء دليل يحفظ الملف المكون من Be ForreSend: function () {// احمل العلامة الفريدة للملف الحالي إلى الخلفية ، والتي يتم استخدامها لإنشاء دليل يحفظ الملف المكون this.owner.options.formdata.filemd5 = filemd5 ؛}}3) تحتاج الخلفية إلى حفظ جميع الملفات المكثفة
// قم بإنشاء دليل لكل ملف وحفظ جميع الملفات المكررة لهذا الملف // الحكم على ما إذا كان قد تم تحميله في قطع إذا (chunks! = null) {system.out.println ("معالجة القطع ...") if (! chunksdir.exists ()) {chunksdir.mkdir () ؛} if (chunk! = null) {// save chunkfile chunkfile = new file (chunksdir.getpath ()+"/" chunk) ؛4) يقوم مكتب الاستقبال بإخطار الواجهة الخلفية لدمج جميع الملفات المكثفة
// يقوم مكتب الاستقبال بإخطار الخلفية لدمج الملفات بعد الانتعاش المنطق: ayrsendfile: function (file) {// 1. إذا تم تحميلها في قطع ، فقم بدمج جميع ملفات القطع من خلال الخلفية // اطلب الخلفية لدمج الملفات $ .ajax ({type: "post" ، url: "$ {pagecontext.request.contextpath}/uploadcheckservlet؟ اسم الملف: file.name} ، نوع البيانات: "json" ، النجاح: الدالة (استجابة) {Alert (response.msg) ؛}}) ؛} // الخلفية دمج جميع الملفات المكررة إذا ("mergechunks" .equals (الإجراء)) request.getParameter ("fileMd5") ؛ string fileName = request.getParameter ("filename") ؛ // اقرأ جميع الملفات في ملف الدليل f = file new (serverpath+"/"+filemd5) ؛ file [] filearray = f.listfiles (filefilter () {// استبعاد الدليل ، كقبول الملف العام (file boolean) {if (pathname.isdirectory ()) {return false ؛} return true ؛}}) ؛ // تحويل إلى مجموعة لتسهيل قائمة الفرز <file> fileList = new ArrayList <ired> (Arrays.Aslist (filearray)) ؛ {if (integer.parseint (o1.getName ()))) <integer.parseint (o2.getName ())) {return -1 ؛ FileOutputStream (outputFile) .getChannel () ؛ // merge filechannel Inchannel ؛ لـ (ملف الملف: fileList) {inchannel = new FileInputStream (file) .getChannel () ؛ inchannel.transferto (0 ، inchannel.size () ، outchannel) ؛ inchannel.close () if (tempfile.isdirectory () && tempfile.exists ()) {tempfile.delete () ؛} // أغلق الدفق Outchannel.close () ؛ reponse.setContentType ("text/html ؛ charset = utf-8") ؛ response.getWriter ().تستمر نقاط توقف الملف الكبيرة
استنادًا إلى تنفيذ تحميل الكتلة ، من السهل جدًا تطبيق الإرسال المستمر نقطة التوقف! ! !
الواجهة الأمامية:
// Time Point 2: إذا كان هناك تحميل كتلة ، فسيتم استدعاء هذه الوظيفة قبل كل كتلة تحميل // block: يمثل كائن الكتلة الحالي Be ForresEnd: function (block) {// 1. طلب ما إذا كانت الخلفية قد حفظت الكتلة الحالية. في حالة وجوده ، تخطي ملف Block لتحقيق وظيفة الإرسال المستمر في نقطة الإيقاف VAR = webuploader.deferred () ؛ // طلب ما إذا كانت الخلفية تحفظ معلومات الملف. إذا تم حفظه ، فسيتم تخطيه. إذا لم يكن الأمر كذلك ، فسيتم إرسال محتوى القطع $ .ajax ({type: "post" ، url: "$ {pagecontext.request.contextpath}/uploadCheckservlet؟ Action = checkchunk" ، data: {//file filed markd5: // the current chunk chunc: lock.end-block.start} ، نوع البيانات: "json" ، النجاح: الدالة (استجابة) {if (response.ifexist) {// الكتل موجودة ، تخطي الكتلة المؤجلة. rEject () ؛ قم بإنشاء الدليل الذي يحفظ الملف يحظر هذا. Owner.options.formdata.filemd5 = fileMd5 ؛ return deferred.promise () ؛ } ،وراء الكواليس:
// تحقق مما إذا كان القطع موجودًا أو يحفظ checkchunk private void (httpservletrequest ، استجابة httpservletresponse) يلقي ioException ، fileNotfoundException {system.out.println ("checkchunk ...") ؛ string filemd5 = request.getParameter ( request.getParameter ("chunksize") ؛ ملف checkfile = ملف جديد (serverPath+"/"+fileMd5+"/"+chunk) ؛ reponse.setContentType ("text/html ؛ charset = utf-8") ؛ checkfile.length () == integer.parseint (chunksize)) {response.getWriter (). write ("{/" ifexist/": 1}") ؛} آخر {response.getWriter (). الكتابة ("{/" ifexist/": 0}") ؛}}}}}}}}}}}}}}}}نقل الملفات في ثوان
قبل جميع طلبات الحظر ، يمكن تنفيذ وظيفة النقل الثانية! ! !
الواجهة الأمامية:
Be ForsEndFile: Function (file) {// إنشاء defferedvar مؤلف = webuploader.deferred () ؛ // 1. احسب العلامة الفريدة للملف ، المستخدمة في الإرسال المستمر نقطة التوقف والنقل الثاني (webuploader.uploader ()). معلومات ... ") ؛}) $ .ajax ({type: "post" ، url: "$ {pagecontext.request.contextpath}/UploadCheCkservlet؟ FILEMD5: FILEMD5} ، نوع البيانات: "json" ، النجاح: الدالة (استجابة) {if (reponse.ifexist) {$ ("#" deferred.resolve () ؛}}}) ؛}) ؛ // إرجاع deferredReturn deferred.promise () ؛} ،وراء الكواليس:
// تحقق مما إذا كانت بيانات MD5 الخاصة بالملف مرتبطة بقاعدة البيانات private void fileCheck (httpservletrequest request ، httpservletresponse report) يرمي ioException ، fileNotfound {String fileMd5 = request.getParameter ("filemd5") ؛ HashMap <String ، String> () ؛ Database.put ("576018603F4091782B68B78F85704A1" ، "01 review.itcast ") ؛ response.setContentType (" text/html ؛ charset = utf-8 ") ؛ if (database.containskey (fileMd5)) {desponse.getWriter (). الكتابة (" {/"ifexist/": 1} ") ؛ما سبق هو مثال على توضيح تحميل ملف Javaweb وتنزيله الذي قدمه المحرر إليك (تقنية تحميل الملفات الرائعة). آمل أن يكون ذلك مفيدًا للجميع. إذا كان لديك أي أسئلة ، فيرجى ترك رسالة لي وسوف يرد المحرر على الجميع في الوقت المناسب. شكرا جزيلا لدعمكم لموقع wulin.com!