في تطوير نظام تطبيقات الويب ، تكون وظائف تحميل الملفات وتنزيلها وظائف شائعة الاستخدام. اليوم ، دعنا نتحدث عن تنفيذ وظائف تحميل الملفات وتنزيلها في Javaweb.
نظرة عامة على تحميل الملف
1. وظيفة تحميل الملف
على سبيل المثال ، القرص الصلب الشبكة! يتم استخدامه لتحميل الملفات وتنزيلها.
لملء سيرة ذاتية كاملة على توظيف Zhilian ، تحتاج أيضًا إلى تحميل الصور.
2. متطلبات تحميل الصفحة
هناك العديد من المتطلبات لتحميل الملفات ، يرجى تذكر:
يجب استخدام النموذج ، وليس طريقة شكل الارتباط التشعبي يجب أن تكون منشورة ، وليس الحصول
يجب أن يكون enctype من النموذج متعددا/data
إضافة حقل نموذج الملف في النموذج ، أي <إدخال type = "file" name = "xxx"/>
<form action = "$ {pagecontext.request.contextpath}/fileuploadservlet" method = "post" enctype = "multipart/form-data"> username: <type type = "text" name = "username"/> <br/> file 1: <input type = "file"/> name = "file2"/> <br/> <إدخال type = "إرسال" value = "إرسال"/> </form>3. قارن الفرق بين نموذج تحميل الملف ونموذج النص العادي
عرض الفرق بين "نموذج تحميل الملف" و "نموذج النص العادي" من خلال httpwatch.
enctype من نموذج تحميل الملف = "multipart/form-data" ، والذي يمثل بيانات النماذج متعددة الأجزاء ؛
يمكن ضبط النماذج النصية العادية دون تعيين سمة enctype:
عندما تكون method = "post" ، تكون القيمة الافتراضية لـ enctype هي التطبيق/x-www-form-urlencoded ، مما يعني أنه عند استخدام الأسلوب = "get" ، تكون القيمة الافتراضية لـ enctype فارغة ولا يوجد نص ، لذلك ليست هناك حاجة لاختبار النموذج النص العادي:
<form action = "$ {pagecontext.request.contextpath}/fileuploadservlet" method = "post"> username: <input type = "text" name = "username"/> <br/> file 1: <input type = "file" name = "file1 value = "إرسال"/> </form>من خلال اختبار httpwatch ، بالنظر إلى هيئة بيانات الطلب للنموذج ، وجدنا أن هناك اسم الملف فقط في الطلب ، ولكن لا يوجد محتوى ملف. وهذا يعني ، عندما لا يكون enctype من النموذج غير متعددة/بيانات النموذج ، لا يحتوي الطلب على محتوى الملف ، ولكن فقط اسم الملف ، مما يعني أنه لا يوجد فرق بين الإدخال: الملف والإدخال: النص في نموذج نص عادي.
نموذج تحميل ملفات الملف:
<form action = "$ {pagecontext.request.contextpath}/fileuploadservlet" method = "post" enctype = "multipart/form-data"> username: <type type = "text" name = "username"/> <br/> file 1: <input type = "file"/> name = "file2"/> <br/> <إدخال type = "إرسال" value = "إرسال"/> </form>من خلال اختبار httpwatch ، ننظر إلى جزء الجسم من بيانات الطلب للنموذج ووجدنا أن جزء الجسم يتكون من مكونات متعددة ، ويتوافق كل مكون مع حقل النماذج ، وأن كل مكون لديه معلومات رأسه الخاصة. أسفل معلومات الرأس ، يوجد خط فارغ ، وتحت الخط الفارغ هو جزء الجسم من الحقل. يتم فصل أجزاء متعددة بواسطة فواصل تم إنشاؤها عشوائيا.
تحتوي معلومات الرأس لحقل النص على معلومات رأس واحدة فقط ، وهي تحديد المحتوى. قيمة معلومات الرأس هذه لها جزأين. الجزء الأول ثابت ، وهو بيانات النموذج ، والجزء الثاني هو اسم الحقل. خلف الخط الفارغ هو الجزء الرئيسي ، والجزء الرئيسي هو المحتوى المملوء في مربع النص.
تحتوي معلومات الرأس لحقل الملف على اثنين من الرؤوس ، إبعاد المحتوى ونوع المحتوى. يوجد اسم ملف إضافي في تحديد المحتوى ، والذي يحدد اسم الملف الذي تم تحميله. يحدد نوع المحتوى نوع الملف الذي تم تحميله. الجزء الرئيسي من حقل الملف هو محتوى الملف.
يرجى ملاحظة أنه نظرًا لأن الملفات التي نحملها كلها ملفات نصية عادية ، أي ملفات TXT ، يمكن عرضها بشكل طبيعي في httpwatch. إذا كانت الملفات التي تم تحميلها هي exe ، mp3 ، وما إلى ذلك ، فإن ما تراه على httpwatch مشوه.
4. متطلبات servlets عند تحميل الملفات
عندما يكون النموذج المقدم هو نموذج تحميل الملف ، هناك أيضًا متطلبات لـ Servlet.
بادئ ذي بدء ، نحتاج إلى التأكد من أن بيانات نموذج تحميل الملف يتم تغليفها أيضًا في كائن الطلب.
تحصل طريقة request.getParameter (سلسلة) على محتوى حرف حقل النموذج المحدد ، ولكن لم يعد نموذج تحميل الملف هو محتوى الحرف ، ولكن محتوى البايت ، لذلك يكون غير صالح.
في هذا الوقت ، يمكنك استخدام طريقة طلب GetInputStream () للحصول على كائن ServleTinputStream. إنها فئة فرعية من InputStream. يتوافق كائن ServleTinputStream مع جزء الجسم من النموذج بأكمله (بدءًا من المقسم الأول إلى النهاية) ، والذي يوضح البيانات في دفق التحليل الذي نحتاجه. بالطبع ، تحليله أمر مزعج للغاية ، وقد زودنا أباتشي بأدوات لتحليلها:
يمكنك محاولة طباعة محتويات Dream.getInputStream () ومقارنة بيانات الطلب في httpwatch.
Public void dopost (طلب httpservletrequest ، استجابة httpservletresponse) يلقي servletexception ، ioException {inputStream in = request.getInputStream () ؛ سلسلة s = ioutils.toString (في) ؛ system.out.println (s) ؛}----------------------------- 7DDD3370AB2Content-Disposition: Form-Data ؛ name = "username" Hello --------------------------- 7ddd3370ab2Content-Disposition: form-data ؛ name = "file1" ؛ filename = "a.txt" نوع المحتوى: text/plainaaa --------------------------- 7ddd3370ab2Content-Disposition: form-data ؛ name = "file2" ؛ filename = "
المشاع
لماذا تستخدم FileUpload:
هناك العديد من المتطلبات لتحميل الملفات ، يرجى تذكر:
يجب أن يكون شكل ما بعد.
يجب أن يكون enctype من النموذج multipart/form-data ؛
إضافة حقل نموذج الملف إلى النموذج ، أي
متطلبات servlet:
لم يعد بإمكانك استخدام request.getParameter () للحصول على بيانات النموذج. يمكنك استخدام request.getInputStream () للحصول على جميع بيانات النموذج ، بدلاً من بيانات عنصر النموذج. هذا يعني أنك لا تستخدم fileUpload ، نحتاج إلى تحليل محتوى request.getInputStream () أنفسنا.
1. نظرة عامة على FileUpload
FileUpload هو مكون تحميل يوفره مكون Apache's Commons. وظيفتها الرئيسية هي مساعدتنا في تحليل الطلب. getInputStream ()
حزم الجرة المطلوبة من قبل مكون FileUpload هي:
commonsfileupload.jar ، حزمة أساسية
Commons-IO.JAR ، حزمة التبعية
2. تطبيق بسيط من fileUpload
الفئات الأساسية من fileUpload هي: diskfileItemFactory ، servletfileupload ، fileItem
خطوات استخدام مكون fileUpload هي كما يلي:
// 1. إنشاء مصنع فئة diskfileitemfactory كائن diskfileitemfactory مصنع = جديد diskfileItemFactory () ؛ // 2. قم بإنشاء كائن محلل باستخدام ServletFilePilePload fileUpload = new ServletFileUpload (المصنع) ؛ // 3. استخدم المحلل لتحليل قائمة كائن الطلب <iretem> list = fileupload.parserequest (request) ؛
DiskfileItemFactory Disk File Class
DiskfileItemFactory (int sizethreshold ، مستودع الملفات)
عند إنشاء مصنع ، حدد حجم المخزن المؤقت للذاكرة وموقع تخزين الملفات المؤقت.
setSizeThreshold (int sizethreshold)
اضبط حجم المخزن المؤقت للذاكرة ، 10K الافتراضي
public void setRepository (مستودع الملفات)
قم بتعيين موقع تخزين الملفات المؤقت ، System.getProperty ("java.io.tmpdir").
المخزن المؤقت للذاكرة: عند تحميل ملف ، يتم حفظ محتوى الملف الذي تم تحميله في المخزن المؤقت للذاكرة أولاً. عندما يتجاوز حجم الملف الذي تم تحميله حجم المخزن المؤقت ، سيتم إنشاء الملفات المؤقتة على جانب الخادم.
موقع تخزين الملفات المؤقتة: تحميل الملفات التي تتجاوز حجم المخزن المؤقت للذاكرة لإنشاء ملفات مؤقتة. يمكن حذف الملفات المؤقتة من خلال طريقة FileItem's DELETE ()
يمثل FileItem كل جزء من البيانات في نموذج تحميل الملف
سنقدم فئة FileItem رسميًا ، وهي النتيجة النهائية التي نريدها. يتوافق كائن FileItem مع عنصر نموذج (حقل النموذج). حقول الملفات والحقول العادية موجودة في شكل. يمكنك استخدام طريقة iSformfield () لفئة FileItem لتحديد ما إذا كان حقل النموذج هو حقل عادي. إذا لم يكن حقلًا عاديًا ، فهو حقل ملف.
ملاحظة: نظرًا لأن نموذج تحميل الملف يتم ترميزه باستخدام multipart/form-data ، يختلف عن ترميز عناوين URL التقليدية ، لا يمكن لجميع طرق getParameter () استخدام setCharacterEncoding () لا يمكن حل المشكلة المشوهة لعناصر الإدخال.
servletfileupload ملف تحميل الفئة الأساسية
3. مثال التحميل البسيط
اكتب مثال تحميل بسيط:
يحتوي النموذج على حقل اسم المستخدم وحقل ملف ؛
Servlet يحفظ الملفات المحملة إلى دليل التحميل ، وعرض اسم المستخدم ، واسم الملف ، وحجم الملف ، ونوع الملف.
الخطوة الأولى:
لإكمال index.jsp ، هناك حاجة إلى نموذج واحد فقط. لاحظ أن النموذج يجب أن يكون منشورًا ، ويجب أن يكون enctype mulitpart/form-data
<form action = "$ {pagecontext.request.contextpath}/fileUploAdServlet" method = "post" enctype = "multipart/form-data"> username: <inputy type = "text" name = "username"/> <br/> file 1: <inputive type = "file"/> value = "إرسال"/> </form>الخطوة 2: أكمل fileUploadServlet
DOPOST public void (طلب httpservletrequest ، استجابة httpservletresponse) يلقي servleTexception ، ioException {// لأنك تريد الطباعة مع الاستجابة ، وتعيين ترميزها reponseContEnttype ("text/html ؛ charset = utf-8") ؛ // إنشاء مصنع diskfileitemfactory dfif = new diskfileItemFactory () ؛ // إنشاء كائن محلل باستخدام المصنع servletfileupload fileUpload = new ServletFileUpload (DFIF) ؛ جرب {// استخدم كائن المحلل المحلل لتحليل الطلب والحصول على قائمة FileItem List <IbourItem> list = fileupload.parserequest (request) ؛ . // إذا كان اسم حقل عنصر النموذج الحالي هو اسم المستخدم إذا (fieldname.equals ("اسم المستخدم")) {// قم بطباعة محتوى عنصر النموذج الحالي ، أي أن المحتوى الذي تم إدخاله بواسطة اسم المستخدم Response. }} else {// إذا لم يكن عنصر النموذج الحالي عنصر نموذج عادي ، فهذا يعني اسم سلسلة حقل الملف = fileItem.getName () ؛ // الحصول على اسم الملف الذي تم تحميله // إذا كان اسم الملف المحمّل فارغًا ، فلا يتم تحديد ملف محمّل إذا (name == null name.isempty ()) {متابعة ؛ } // احصل على المسار الحقيقي ، المقابل لـ $ {project directory}/uploads. بالطبع ، يجب أن يحتوي هذا الدليل على string savepath = this.getServletContext (). getRealPath ("/uploads") ؛ // إنشاء كائن ملف من خلال دليل التحميل وملف اسم الملف = ملف جديد (SavePath ، name) ؛ // احفظ ملف التحميل إلى الموقع المحدد fileitem.write (ملف) ؛ // اطبع اسم تحميل ملف response.getWriter (). print ("تحميل اسم ملف:" + name + "<br/>") ؛ // طباعة حجم ملف التحميل. // اطبع نوع file file response.getWriter (). print ("نوع التحميل نوع الملف:" + fileItem.getContentType () + "<br/>") ؛ }}} catch (استثناء e) {رمي servleTexception (e) ؛ }}تفاصيل تحميل الملف
1. ضع الملف الذي تم تحميله في دليل الويب
إذا لم يتم تخزين الملفات التي تم تحميلها بواسطة المستخدم في دليل الويب الخاص بـ Web-INF ، فيمكن المستخدم الوصول مباشرة إلى الملفات التي تم تحميلها من خلال المتصفح ، وهو أمر خطير للغاية.
إذا قام المستخدم بتحميل ملف A.JSP ثم يقوم المستخدم بالوصول إلى ملف A.JSP من خلال المتصفح ، فسيتم تنفيذ المحتوى في A.JSP. إذا كان هناك البيان التالي في A.JSP: Runtime.getRuntime (). ثم سوف ...
عادةً ما نقوم بإنشاء دليل تحميل في دليل Web-Inf لتخزين الملفات التي تم تحميلها. للعثور على هذا الدليل في Servlet ، نحتاج إلى استخدام طريقة getRealPath (سلسلة) من servletContext. على سبيل المثال ، هناك البيان التالي في مشروع التشغيل الخاص بي:
servletContext servletContext = this.getServletContext () ؛ String SavePath = servletContext.getRealPath ("/web-inf/uploads") ؛SavePath هو: f:/tomcat6_1/webapps/upload1/web-inf/uploads.
2. اسم الملف (المسار الكامل ، اسم الملف)
قد يكون اسم الملف الذي تم تحميله هو المسار الكامل:
اسم ملف التحميل الذي تم الحصول عليه بواسطة IE6 هو المسار الكامل ، في حين أن اسم ملف التحميل الذي تم الحصول عليه بواسطة المتصفحات الأخرى هو مجرد اسم الملف. ما زلنا بحاجة إلى التعامل مع مشكلة اختلافات المتصفح
اسم السلسلة = file1fileItem.getName () ؛ reponse.getWriter (). print (name) ؛
باستخدام متصفحات مختلفة للاختبار ، ستعيد IE6 المسار الكامل لتحميل الملف. لا أعرف ما الذي يفعله IE6 ، وهو ما يجلب لنا الكثير من المتاعب ، وهو التعامل مع هذه المشكلة.
من السهل جدًا التعامل مع هذه المشكلة. سواء كان ذلك مسارًا كاملاً أم لا ، فإننا نعترض فقط المحتوى بعد آخر "/"
اسم السلسلة = file1fileItem.getName () ؛ int lastIndex = name.lastindexof ("//") ؛ // احصل على موضع آخر "/" if (lastIndex! = -1) {// لاحظ أنه إذا لم يكن المسار الكامل ، فلن يكون هناك "/". name = name.subString (LastIndex + 1) ؛ // احصل على اسم الملف} reponse.getWriter (). print (name) ؛3. مشكلة مشوهة الصينية
يحتوي اسم الملف الذي تم تحميله على اللغة الصينية:
عندما يحتوي الاسم الذي تم تحميله على اللغة الصينية ، تحتاج إلى ضبط الترميز. يوفر لنا مكون Commons-FilePload بطريقتين لتعيين الترميز:
request.setcharacterencoding (سلسلة): هذه الطريقة هي الطريقة الأكثر دراية نحن.
fileupload.setheaderencdoing (سلسلة): هذه الطريقة لها أولوية أعلى من السابق
يحتوي محتوى الملف الخاص بالملف الذي تم تحميله على الصينية:
عادةً ما لا نحتاج إلى الاهتمام بمحتوى تحميل الملفات ، لأننا سنحفظ الملفات التي تم تحميلها على محرك الأقراص الثابتة! بمعنى آخر ، كيف يبدو الملف وما يبدو عليه على الخادم!
ولكن إذا كان لديك مثل هذا الشرط وكان عليك عرض محتويات الملف التي تم تحميلها على وحدة التحكم ، فيمكنك استخدام fileItem.getString ("UTF-8") للتعامل مع الترميز
محتوى الملف النصي ومحتوى عنصر النموذج العادي استخدم GetTring ("UTF-8") لفئة FileItem للتعامل مع الترميز.
4. مشكلة تحميل الملف مع نفس الاسم (إعادة تسمية الملف)
عادةً ما نقوم بحفظ الملف الذي تم تحميله بواسطة المستخدم إلى دليل التحميل ، ولكن ماذا لو قام المستخدم بتحميل ملف بنفس الاسم؟ هذا سوف يسبب التغطية. تتمثل طريقة التعامل مع هذه المشكلة في استخدام UUID لإنشاء اسم فريد ، ثم استخدام "_" لتوصيل الاسم الأصلي الذي تم تحميله بواسطة الملف.
على سبيل المثال ، يتم تحميل الملف الذي تم تحميله بواسطة المستخدم "My One Inch Photo.jpg". بعد المعالجة ، هو اسم الملف هو: "891B3881395F4175B969256A3F7B6E10_MY بوصة واحدة photo.jpg". لن تتسبب هذه الطريقة في فقدان الملف. بسبب تفرد UUID ، فإن الملف الذي تم تحميله له نفس الاسم ، ولكن لن تكون هناك مشكلة في نفس الاسم على جانب الخادم.
Public void dopost (طلب httpservletrequest ، استجابة httpservletresponse) يلقي servletexception ، ioException {request.setcharacterencoding ("UTF-8") ؛ diskfileItemFactory dfif = new diskfileItemFactory () ؛ servletfileUpload fileUpload = new servletfileUpload (dfif) ؛ حاول {list <IptiTem> list = fileupload.parserequest (request) ؛ // احصل على عنصر النموذج الثاني ، لأن عنصر النموذج الأول هو اسم المستخدم ، والثاني هو عنصر fileItem fileItem = list.get (1) ؛ name string = fileItem.getName () ؛ // احصل على اسم الملف // إذا كان العميل يستخدم IE6 ، فأنت بحاجة إلى الحصول على اسم الملف من PATH PATH LASTINDEX = NAME.LASTINDEXOF ("//") ؛ if (lastIndex! = -1) {name = name.subString (lastIndex + 1) ؛ } // الحصول على الملف المحمّل SavePath = this.getServletContext (). getRealPath ("/web-inf/uploads") ؛ String uuid = commonutils.uuid () ؛ // إنشاء اسم fileName uuid = uuid + "_" + name ؛ // اسم الملف الجديد هو uuid + underscore + name Original // إنشاء كائن ملف محمّل ، وسيتم حفظ ملف filded ، fildauph ، // حفظ ملف item.write (ملف) ؛ } catch (استثناء e) {رمي servleTexception (e) ؛ }}5. لا يمكن للدليل تخزين الكثير من الملفات (دليل تخزين لتفكك)
لا ينبغي أن يكون هناك الكثير من الملفات المخزنة في الدليل. بشكل عام ، يتم تخزين 1000 ملف في دليل ، وإذا كان هناك الكثير ، فسيكون "متبرعًا" جدًا عند فتح الدليل. يمكنك محاولة طباعة دليل C:/Windows/System32 ، ستشعر به
وهذا هو ، نحن بحاجة إلى وضع الملفات التي تم تحميلها في أدلة مختلفة. ومع ذلك ، لا يمكن استخدام دليل واحد لكل ملف تم تحميله ، لأن هذه الطريقة ستؤدي إلى الكثير من الدلائل. لذلك يجب أن نستخدم بعض الخوارزمية "للانفصال"!
هناك العديد من الطرق لتفكيكها ، مثل استخدام التواريخ لتفكيكها ، وإنشاء دليل كل يوم. يمكنك أيضًا استخدام الحرف الأول من اسم الملف لإنشاء دليل ، ويتم وضع الملفات التي تحمل نفس الحرف الأولي في نفس الدليل.
خوارزمية كسر التاريخ: إذا كان هناك الكثير من الملفات التي تم تحميلها في يوم معين ، فسيكون هناك أيضًا الكثير من ملفات الدليل ؛
خوارزمية كسر الرسالة الأولى: إذا كان اسم الملف باللغة الصينية ، لأن هناك الكثير من الصينيين ، فسيؤدي ذلك إلى الكثير من الدلائل.
نستخدم خوارزمية التجزئة هنا لتفكيكها:
احصل على علامة التجزئة لاسم الملف: int hcode = name.hashcode ()
احصل على 4 بتات من Hcode ، ثم قم بتحويلها إلى أحرف سداسية عشرية للحصول على 5 ~ 8 بتات من Hcode ، ثم تحويلها إلى أحرف سداسي عشرية لإنشاء سلسلة دليل باستخدام هاتين الحرفين السداسي. على سبيل المثال ، الأحرف السفلية ذات 4 بت هي "5"
تتمثل ميزة هذه الخوارزمية في وجود 16 دليلًا كحد أقصى في دليل التحميل ، ويتم إنشاء 16 دليلًا كحد أقصى في كل دليل ، أي 256 دليلًا ، ويتم وضع جميع الملفات المحملة في هذه الدلائل الـ 256. إذا كان الحد الأقصى لعدد كل دليل هو 1000 ملف ، فيمكن حفظ ما مجموعه 256000 ملف.
على سبيل المثال ، اسم ملف التحميل هو: new text document.txt ، ثم الحصول على رمز التجزئة من "مستند النص الجديد. txt" ، ثم الحصول على 4 أرقام من رمز التجزئة ، و 5 إلى 8 أرقام. إذا كانت البتات السفلية 4: 9 و 5 ~ 8 بت هي 1 ، فإن مسار حفظ الملف هو تحميل/9/1/
int hcode = name.hashCode () ؛ // احصل على hashcode لاسم الملف // احصل على 4 بتات منخفضة من hcode وتحويلها إلى سلسلة السلسلة السداسية dir1 = Integer.ToHexString (hcode & 0xf) ؛ >>> 4 & 0xf) ؛ // قم بتوصيل مسار حفظ الملف إلى المسار الكامل SavePath = SavePath + "/" + Dir1 + "/" + Dir2 ؛ // لأن هذا المسار قد لا يكون موجودًا ، قم بإنشائه ككائن ملف ، ثم إنشاء سلسلة دليل للتأكد من وجود الدليل بالفعل قبل حفظ ملف الملف (SavePath) .mkdirs () ؛
6. حدود الحجم للملفات التي تم تحميلها الفردية
من السهل جدًا الحد من حجم الملفات التي تم تحميلها ، فقط setFilesizeMax (طويل) من فئة servletfileupload. المعلمة هي عدد الحد الأعلى للبايت للملف الذي تم تحميله. على سبيل المثال ، servletfileupload.setFilesizeMax (1024*10) يعني أن الحد الأعلى هو 10 كيلو بايت.
بمجرد أن يتجاوز الملف الذي تم تحميله الحد الأعلى ، سيتم إلقاء استثناء FileUploAdbase.FilesizeLiMitexceedEdException. يمكننا الحصول على هذا الاستثناء في Servlet والإخراج "الملف الذي تم تحميله يتجاوز الحد" إلى الصفحة.
Public void dopost (طلب httpservletrequest ، استجابة httpservletresponse) يلقي servletexception ، ioException {request.setcharacterencoding ("UTF-8") ؛ diskfileItemFactory dfif = new diskfileItemFactory () ؛ servletfileUpload fileUpload = new servletfileUpload (dfif) ؛ // قم بتعيين الحد الأعلى للملف الفردي الذي تم تحميله على 10kb fileUpload.setFilesizEmax (1024 * 10) ؛ حاول {list <IptiTem> list = fileupload.parserequest (request) ؛ // احصل على عنصر النموذج الثاني ، لأن عنصر النموذج الأول هو اسم المستخدم ، والثاني هو عنصر fileItem = list.get (1) ؛ name string = fileItem.getName () ؛ // احصل على اسم الملف // إذا كان العميل يستخدم IE6 ، فأنت بحاجة إلى الحصول على اسم الملف من PATH PATH LASTINDEX = NAME.LASTINDEXOF ("//") ؛ if (lastIndex! = -1) {name = name.subString (lastIndex + 1) ؛ } // الحصول على الملف المحمّل SavePath = this.getServletContext (). getRealPath ("/web-inf/uploads") ؛ سلسلة uuid = commonutils.uuid () ؛ // إنشاء اسم ملف uuid uuid = uuid + "_" integer.toHexString (hcode & 0xf) ؛ // احصل على أقل 5 ~ 8 بت من Hcode وقم بتحويله إلى سلسلة سلسلة سداسية Dir2 = Integer.ToHexString (Hcode >>> 4 & 0xf) ؛ // قم بتوصيل المسار Save File إلى مسار كامل SavePath = SavePath + "/" + Dir1 + "/" + Dir2 ؛ // لأن هذا المسار قد لا يكون موجودًا ، قم بإنشاء كائن ملف ، ثم إنشاء سلسلة دليل للتأكد من وجود الدليل بالفعل قبل حفظ الملف الجديد (SavePath) .mkdirs () ؛ // إنشاء كائن ملف ، وسيتم حفظ الملف الذي تم تحميله على المسار المحدد بواسطة هذا الملف // SavePath ، أي الملف الذي تم تحميله Save Directory // filename ، اسم الملف ، اسم الملف ؛ // Save FileItem.write (file) ؛ } catch (استثناء e) {// حدد ما إذا كان نوع الاستثناء الذي تم إلقاؤه هو fileuploadbase.filesizeLimitexentedException // إذا كان الأمر كذلك ، فهذا يعني أنه تم تجاوز الحد عند تحميل الملف. if (e eastyof fileuploadbase.filesizeLimitexceedEdException) {// حفظ رسالة الخطأ في طلب request.setAttribute ("msg" ، "فشل التحميل! تجاوز الملف المحمّل 10 كيلو بايت!") ؛ // توجيه إلى صفحة index.jsp! في صفحة index.jsp ، تحتاج إلى استخدام $ {msg} لعرض طلب رسالة الخطأ. getRequestDispatcher ("/index.jsp"). يعود؛ } رمي ServleTexception (E) ؛ }}7. الحد الإجمالي للحجم لتحميل الملفات
قد يسمح النموذج لتحميل الملف بتحميل ملفات متعددة ، على سبيل المثال:
في بعض الأحيان نحتاج إلى الحد من حجم الطلب. وهذا يعني ، الحد الأقصى لعدد البايتات لهذا الطلب (مجموع جميع عناصر النماذج)! تنفيذ هذه الوظيفة أمر بسيط للغاية. تحتاج فقط إلى استدعاء طريقة SetSizeMax (طويلة) لفئة servletfileupload.
على سبيل المثال ، FileUpload.SetSizemax (1024 * 10) ؛ ، الحد الأعلى للطلب بأكمله هو 10 كيلو بايت. عندما يتجاوز حجم الطلب 10 كيلو بايت ، فإن طريقة parserequest () لفئة servletFileUpload ستعمل على إلقاء استثناء fileuploadbase.sizelimitexceedEdException.
8. حجم ذاكرة التخزين المؤقت والدليل المؤقت
فكر في الأمر ، إذا قمت بتحميل فيلم Blu-ray ، وحفظ الفيلم إلى الذاكرة أولاً ، ثم نسخه إلى القرص الصلب الخادم من خلال الذاكرة ، فهل يمكن تناول ذاكرتك؟
لذلك ، لا يمكن لمكون FileUpload حفظ جميع الملفات في الذاكرة. سيحدد FileUpload ما إذا كان حجم الملف يتجاوز 10 كيلو بايت. إذا كان الأمر كذلك ، احفظ الملف على القرص الثابت. إذا لم يتجاوزها ، احفظها في الذاكرة.
10KB هي القيمة الافتراضية لـ FileUpload ، يمكننا تعيينها.
عندما يتم حفظ الملف إلى القرص الثابت ، يقوم FileUpload بحفظ الملف إلى الدليل المؤقت للنظام. بالطبع ، يمكنك أيضًا تعيين الدليل المؤقت
Public void dopost (طلب httpservletrequest ، استجابة httpservletresponse) يلقي servletexception ، ioException {request.setcharacterencoding ("UTF-8") ؛ diskfileItemFactory dfif = new diskfileItemFactory (1024*20 ، ملف جديد ("f: // temp")) ؛ servletfileUpload fileUpload = new servletfileUpload (dfif) ؛ حاول {list <IptiTem> list = fileupload.parserequest (request) ؛ fileItem fileItem = list.get (1) ؛ اسم السلسلة = fileItem.getName () ؛ String SavePath = this.getServletContext (). getRealPath ("/web-inf/uploads") ؛ ] + 1) ؛ File (SavePath) .mkdirs ().تنزيل الملف
1. قم بتنزيل 1 من خلال Servlet
يجب وضع الموارد التي تم تنزيلها في دليل Web-Inf (لا بأس طالما أن المستخدم لا يمكنه الوصول مباشرة من خلال المتصفح) ، ثم تنزيله عبر Servlet.
امنح الارتباط التشعبي في صفحة JSP ، ارتباطًا بـ DownloadServlet ، وقم بتوفير اسم الملف للتنزيل. ثم يحصل DownloadServlet على المسار الحقيقي للملف ويكتب الملف إلى دفق Response.getOutputStream ().
تنزيل
<Body> هذه هي صفحة JSP الخاصة بي. <br> <a href = "<c: url value = '/downloadServlet؟ path = a.avi' //>"> a.avi </a> <br/> <a href = "<c: url value = '/downloadServlet؟ path = a.jpg' ///>" value = '/downloadServlet؟ path = a.txt' ////> "> a.txt </a> <br/> </body>
تنزيلات java
DOGED void public (طلب httpservletrequest ، استجابة httpservletresponse) يلقي servleTexception ، ioException {String filename = request.getParameter ("path") ؛ string filePath = this.getServletContext (). ملف الملف = ملف جديد (FilePath) ؛ if (! file.exists ()) {response.getWriter (). print ("الملف الذي تريد تنزيله غير موجود!") ؛ يعود؛ } ioutils.copy (FileInputStream جديد (ملف) ، استجابة. getOutputStream ()) ؛}الرمز أعلاه لديه المشاكل التالية:
1. يمكنك تنزيل A.Avi ، ولكن اسم الملف في مربع التنزيل هو DownloadServlet ؛
2. لا يمكنك تنزيل A.JPG و A.TXT ، ولكن عرضها في الصفحة.
2. قم بتنزيل 2 من خلال Servlet
دعنا نتعامل مع المشكلة في المثال السابق ، بحيث يمكن لمربع التنزيل عرض اسم الملف الصحيح ، ويمكنك تنزيل ملفات A.JPG و A.TXT
التعامل مع المشكلة أعلاه عن طريق إضافة رأس تحديد المحتوى. عند ضبط رأس تحديد المحتوى ، سيظهر المتصفح مربع التنزيل
ويمكنك أيضًا تحديد اسم الملف الذي تم تنزيله من خلال رأس تحديد المحتوى!
اسم ملف السلسلة = request.getParameter ("path") ؛ string filePath = this.getServletContext (). ملف الملف = ملف جديد (FilePath) ؛ if (! file.exists ()) {response.getWriter (). print ("الملف الذي تريد تنزيله غير موجود!") ؛ يعود؛ } response.addheader ("disposition content" ، "filename =" + filename) ؛ ioutils.copy (FileInputStream جديد (ملف) ، استجابة. getOutputStream ()) ؛على الرغم من أن الكود أعلاه يمكنه بالفعل التعامل مع تنزيل الملفات مثل TXT و JPG ، وكذلك التعامل مع مشكلة عرض أسماء الملفات في مربع التنزيل ، إذا كان اسم الملف الذي تم تنزيله باللغة الصينية
3. قم بتنزيل 3 من خلال Servlet
فيما يلي مشكلة التعامل مع عرض الصينيين في مربع التنزيل!
في الواقع ، هذا السؤال بسيط للغاية. تحتاج فقط إلى تشفير الصينية من خلال عنوان URL!
تنزيل
<a href = "<c: url value = '/downloadServlet؟ path = هذا القاتل ليس بارد جدًا. avi' //>"> هذا القاتل ليس بارد جدًا. href = "<c: url value = '/downloadServlet؟ path = description.txt'/>" description.txt </a> <br/>
تنزيلات java
اسم ملف السلسلة = طلب. // بالطبع ، إذا كنت تستخدم "مرشح الترميز العالمي" ، فأنت لست بحاجة إلى التعامل معه هنا اسم الملف = سلسلة جديدة (filename.getBytes ("ISO-8859-1") ، "UTF-8") File (filepath) ؛ if (! file.exists ()) {response.getWriter (). print ("الملف الذي تريد تنزيله غير موجود!") ؛ إرجاع ؛} // ستستخدم جميع المتصفحات الترميز المحلي ، أي أن نظام التشغيل الصيني يستخدم GBK // بعد أن يستقبل المتصفح اسم الملف هذا ، وسيستخدم ISO-8859-1 لفك تشفير اسم الملف = سلسلة جديدة (filename.getBytes ("gbk") ، "ISO-8859-1") filename) ؛ ioutils.copy (FileInputStream جديد (ملف) ، reponse.getOutputStream ()) ؛ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.