1. Обзор загрузки файла
Чтобы реализовать функцию загрузки файла в веб -разработку, требуются два шага:
1. Сложите загрузку элементов ввода на веб -страницу
<form action = "#" method = "post" enctype = "multipart/form-data"> <input type = "file" name = "filename1"/> <br> <input type = "file" name = "filename2"/> <br> <input type = "pospe" value = "upload"/> <form> <!-1. Метод формы должен быть post 2. После установки этого значения, когда браузер загружает файл, он прикрепит данные файла к корпусу сообщений HTTP -запроса и использует протокол MIME для описания загруженного файла, чтобы облегчить приемник и обработать загруженные данные. 3. Имя атрибута ввода должен быть установлен, в противном случае браузер не отправит загруженные данные файла. ->
2. Прочтите данные загрузки файла в сервисе и сохраните его на жесткий диск сервера
Объект запроса предоставляет метод GetInputStream, с помощью которого можно прочитать данные, представленные клиентом. Однако, поскольку пользователи могут загружать несколько файлов одновременно, это очень хлопотная задача для программы и непосредственно читать загруженные данные со стороны сервлета и разрабатывать соответствующие данные файла отдельно.
Например, следующее приведено некоторое содержимое протокола HTTP запроса, отправленного перехваченным браузером при загрузке файла:
Приемный язык: ZH-HANS-CN, ZH-HAN; Q = 0,5Content-Type: Multipart/Form-Data; Граница = --------------------------- 7DFA01D1908A4UA-CPU: AMD64ACCETE-ENCODING: GZIP, DeflateUser-Agent: Mozilla/5,0 (Windows NT 6.2; Win64; X64; Trident/7,0; RV: 11,0), как и GeckoContent-Longe: 653HOST: LocalHost: 808.connection: 808.connection: 808. Keep-AlivePragma: No-CacheCookie: JSessionId = 11CEFF8E271AB62CE676B5A87B746B5F ----------------------------- 7DFA01D1908A4Content-Disposition: Форма-дата; name = "username" Zhangsan ----------------------------- 7DFA01D1908A4Content-Disposition: Form-Data; name = "userPass" 1234 --------------------------------- 7DFA01D1908A4Content-Disposition: Form-Data; name = "filename1"; filename = "c: /users/asus/desktop/upload.txt" content-type: text/plainthis это содержимое первого файла! ----------------------------- 7DFA01D1908A4Content-Disposition: Form-Data; name = "filename1"; filename = "c:/users/asus/desktop/upload2.txt" content-type: text/plain это содержимое второго файла! Привет ----------------------------- 7DFA01D1908A4--
Из приведенных выше данных можно увидеть, что трудно написать надежную и стабильную программу, если вы вручную разделите и читаете данные. Поэтому, чтобы облегчить пользователям обработку данных загрузки, организация Apache Open Source предоставляет компонент с открытым исходным кодом (Commons-FileUpload), используемый для обработки загрузки файлов формы. Этот компонент обладает отличной производительностью, и его API очень прост в использовании, что позволяет разработчикам легко реализовать функции загрузки веб -файлов. Поэтому в веб-разработке функция загрузки файла обычно реализуется с использованием компонента Commons-FilePload.
Необходимо импортировать два пакета JAR: Commons-FileUpload, Commons-IO
response.setContentType ("text/html; charset = utf-8"); // Установить запрос кодирования ответа. setcharacterencoding ("UTF-8"); Printwriter writer = response.getwriter (); // Получить выходной сигнал выходного потока ServletInputStream = request.getInputStream (); // Получить поток запроса запроса/* 1. Создайте объект DiskFileItemFactory, установите размер буфера и временный файл. Sizethreshold, этот параметр устанавливает размер буфера памяти, значение по умолчанию составляет 10K. Когда файл загрузки больше размер буфера, компонент FileUpload будет загружать файл, используя временный кэш файла* @param java.io.file Repository, этот параметр определяет временный каталог файлов, значение по умолчанию - System.getProperty ("java.io.tmpdir"); * * Если используется конструктор без параметров, SetSizethreshold (int sizethreshold), setRepository (java.io.file Repository) * Метод устанавливается вручную */ diskfileitemfactory factory = new DiskFileTemFactory (); int sizethreshold = 1024*1024; factory.setsizethershold (Sizethreshold); File Repository = new File (request.getSession (). GetServletContext (). GetRealPath ("temp")); // System.out.println (request.getSession (). GetServletContext (). GetRealPath ("temp")); // system.out.println (request.getRealpath ("temp"); factory.setRepository (Repository); / * * 2. Используйте объект DiskFileItemFactory, чтобы создать объект ServletFileUpload и установить размер загруженного файла * * объект ServletFileUpload отвечает за обработку загруженных данных файла и инкапсулирует каждый входной элемент в форму в FileItem * Общие методы этого объекта: * Boolean ISmultiPartContent (запрос); Определите, является ли загруженная форма Multipart/Form-Data Type* List Parserequest (запрос); Проанализируйте объект запроса, оберните каждый входной элемент в форму в объект FileItem и возвращайте коллекцию списков, которая сохраняет все файлы fileItems* void setFilesizeMax (long filesizemax); Установите максимальное значение одного загруженного файла* void setsizemax (long sizemax); Установите максимальное значение общего количества загруженного Wenjiang* void setheadencoding (); Установите формат кодирования, чтобы решить проблему загруженного кода имена файлов*/ ServletFileUpload upload = new ServletFileUpload (Factory); upload.setheAderencoding ("UTF-8"); // Установите формат кодирования для решения проблемы загрузки искаженного кода имен файлов/** 3. Вызовите метод ServletFileUpload.parseRequest, чтобы проанализировать объект запроса и получить объект списка, который сохраняет все загруженное содержимое*/sirectem> parseRequest = null; try {parserequest = upload.parserequest (запрос); } catch (fileuploadexception e) {e.printstacktrace (); } / * * 4. Итерация над списком. Каждый итерация объекта FileItem, вызовите его метод Isformfield, чтобы определить, является ли это загрузкой файла* true, это означает, что это нормальное поле формы, а затем вызовите методы GetFieldName и GetString, чтобы получить имя поля и значение поля* false - это файл загрузки, а затем вызовите getInputStream для получения потока данных, тем самым считывающий данные загрузки**** этого объекта: * Boolean isformfield (); Определяет, является ли FileItem объектом загрузки файла или обычным объектом формы * true означает, что это нормальное поле формы, * затем вызовите GetFieldName и методы GetString, чтобы получить имя поля и значение поля * false в качестве файла загрузки, * затем вызовите getName (), чтобы получить имя файла файла загрузки. ПРИМЕЧАНИЕ. Некоторые браузеры несут клиентские пути и необходимо вычесть себя * Call getInputStream () метод для получения потока ввода данных, чтобы прочитать данные загрузки * delete (); означает, что после закрытия потока ввода FileItem удаляется временные файлы. */for (fileitem fileitem: parserequest) {if (fileitem.isformfield ()) {// Представляет нормальное поле if ("username" .equals (fileitem.getfieldname ()))) {string username = fileitem.getString (); writer.write ("Ваше имя пользователя:"+имя пользователя+"<br>"); } if ("userpass" .equals (fileitem.getfieldname ()))) {string userpass = fileitem.getString (); writer.write ("Ваш пароль:"+userpass+"<br>"); }} else {// означает загруженный файл // файлы, загруженные различными браузерами, может иметь имя пути, и вам нужно вырезать String clientName = fileitem.getName (); String filename = ""; if (clientname.contains ("//")) {// if "/" означает имя с пути, последнее имя файла - это перехвата filename = clientName.substring (clientName.lastIndexof ("//")). substring (1); } else {filename = clientName; } Uuid randomuuid = uuid.randomuuid (); // генерировать 128-битный длинный глобально уникальный идентификатор идентификатора = randomuuid.tostring ()+имя файла; / * * Разработка алгоритма генерации каталогов. Если общее количество файлов, загружаемых пользователем, составляют заказы на миллионы заказа или более, размещение их в одном и том же каталоге приводит к тому, что индекс файла будет очень медленным. Следовательно, очень необходимо разработать структуру каталога для хранения файлов рассеянным образом, и разумно * преобразовать алгоритм хэш-хэш UUID в меньший диапазон, * преобразовать хэш-код UUID в 8-битный EG Octal String, * Начиная с первого бита этой строки, каждый символ представляет собой управляющий первый уровень. Очень эффективная структура каталогов как для сервера, так и для операционной системы*/ int hashuuiid = randomuuid.hashcode (); String hexuuid = integer.tohexstring (hashuuid); //System.out.println(hexuuid); // Получить абсолютный путь, в какой папку хранит загруженный файл в string filePath = request.getSession (). GetServletContext (). GetRealPath ("upload"); для (char c: hexuuid.thararray ()) {filepath = filePath+"/"+c; } // Если каталог не существует, генерируйте файл каталога восьмого уровня filePathfile = new File (filePath); if (! filepathfile.exists ()) {filepathfile.mkdirs (); } // Читать файл из потока ввода запроса и записать в Server InputStream inputStream2 = fileitem.getInputStream (); // Создать файл в файле файла на стороне сервера = новый файл (filePath+"/"+filename); BufferedOutputStream bos = new BufferedOutputStream (New FileOutputStream (File)); Byte [] buffer = новый байт [10*1024]; int len = 0; while ((len = inputstream2.read (буфер, 0, 10*1024))! =-1) {bos.write (буфер, 0, len); } writer.write ("Вы загрузили файл"+clientName+"успешно <br>"); // закрыть ресурс bos.close (); inputStream2.close (); }} // Обратите внимание, что загруженный файл Eclipse сохраняется в работающем каталоге проекта, а не в каталоге проекта в рабочей области.2. Проблемы, которые требуют особого внимания для загрузки файлов: (все эти проблемы предоставляются простыми решениями в приведенном выше коде)
1. Где хранить файлы
Чтобы обеспечить безопасность сервера, загруженный файл должен быть сохранен в каталоге Web-Inf приложения, или каталог, не управляемый веб-сервером. Если пользователь загружает файл с помощью исполняемого кода, такого как файл JSP, и обращается к нему в соответствии с путем доступа к сплайсингу, он может сделать что -либо на стороне сервера.
2. Чтобы предотвратить загрузку нескольких пользователей с тем же именем файла, что приводит к перезагрузке файлов, загрузка файла должен убедиться, что загруженный файл имеет уникальное имя файла .
Переименование с использованием UUID + USERLOAD Имя файла
О uuid:
UUID (универсально уникальный идентификатор) глобально уникальный идентификатор относится к числу, генерируемому на машине, что гарантирует, что он уникален для всех машин в одно и то же время и пространство. Согласно стандартам, установленным Фондом Open Software Foundation (OSF), адрес Ethernet Card, наносекундное время, идентификационный код чипа и много возможных чисел используется. Он состоит из комбинации следующих частей: текущая дата и время (первая часть Uuid связана со временем. Если вы генерируете другой Uuid через несколько секунд после создания UUID, первая часть отличается, остальная часть одинакова), последовательность часов, глобально уникальная идентификация машины IEEE (если есть сетевая карта, это сетевая карта, вы получается в сетевой карте, и нет сетевой карты, и не получается сетевая карта, и не получается сетевая карта, и не получается сетевая карта, и не получается сетевая карта, и нет сетевой карты, и нет сетевой карты, и нет сетевой карты, и нет сетевой карты. это то, что сгенерированная строка, будет относительно длинной.
Это 128-битное длинное число, обычно выраженное в шестнадцатеричной. Основная идея алгоритма состоит в том, чтобы генерировать GUID в сочетании с сетевой картой машины, локальным временем и мгновенным номером. Теоретически, если машина генерирует 100 000 гид в секунду, может быть гарантировано (в смысле вероятности), что 3240 лет не будут повторяться.
Начиная с JDK1.5, генерирование UUIDS стало простой вещью, думая, что JDK внедрил UUIDS:
java.util.uuid, просто называйте это напрямую.
Uuid uuid = uuid.randomuuid ();
String s = uuid.randomuuid (). Полем
UUID состоит из шестнадцатизначного числа, которое выражается в форме
550E8400-E29B-11D4-A716-4466555440000
3. Чтобы предотвратить слишком много файлов в одном каталоге и повлиять на скорость чтения и записи файла, программа, которая обрабатывает загрузку файлов, должна выбрать соответствующий алгоритм генерации структуры каталогов на основе общего возможного объема загрузки, и хранить загруженные файлы в дисперсированном виде. Например, используйте метод хэшкода для создания многоуровневого каталога.
4. Если разные пользователи загружают один и тот же файл, нет необходимости хранить много копий одного и того же файла на стороне сервера. Это пустая трата ресурсов. Алгоритм должен быть разработан для решения проблемы дублирования файлов.
5. Технологический принцип JSP автоматически реализует многопоточное. Поэтому разработчикам не нужно рассматривать многопоточные операции загрузки файлов
3. Скачать файл
<% Arraylist <string> filenames = new ArrayList <string> (); filenames.add ("file/aa.txt"); filenames.add ("file/bb.jpg"); Для (строкового файла: имена файлов) { %> <form action = "downloadservlet" method = "get"> <input type = "hidden" name = "filename" value = "< %= filename %>" /> <input type = "value =" download: < %= filename %> " /> < /> < %} %> %> request. String fileName = request.getParameter ("filename"); String urlName = urlencoder.encode (имя файла, "UTF-8"); // Предотвратить китайский искаженный ответ.setheader ("Контент-дискуссия", "Приложение; filename ="+urlName); FileInputStream fis = new FileInputStream (новый файл (request.getSession (). GetServletContext (). GetRealPath (имя файла))); BufferedInputStream bis = new BufferedInputStream (FIS); ServletOutputStream sos = response.getOutputStream (); Byte [] buffer = новый байт [1024]; int len = 0; while ((len = bis.read (буфер, 0, 1024))! =-1) {sos.write (буфер, 0, len); } bis.close (); fis.close ();4. Используйте компонент Smartupload в SSH, чтобы упростить загрузку и загрузку файлов
Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.