Что такое загрузка файлов?
Загрузка файла - это сохранить информацию пользователя.
Зачем мне загружать файл?
Когда пользователь регистрируется, пользователю может потребоваться отправить фотографию. Тогда это фото должно быть сохранено.
Загрузить компоненты (инструменты) Почему нам нужно использовать инструмент загрузки?
Зачем нам нужно загружать компоненты? Когда мы хотим получить данные клиента, мы обычно получаем их с помощью метода GetParameter ().
Загруженные данные файла делятся на протокол MIME, а форма инкапсулируется в двоичном изображении. Другими словами: GetParameter () не может получить данные загруженного файла.
Давайте сначала посмотрим, как загрузки файлов http приносят с собой данные
Страница JSP, форма должна указать Enctype: Multipart/Form-Data
<form action = "$ {pagecontext.request.contextpath}/servlet/uploadservlet1" ectype = "multiply/form-data" method = "post"> upload user: <input type = "text" name = "username"> <br/> файл загрузки 1: <input = "file" name = "file1"> <br /> upload 2: "inpit name =" name = "> <br/> upload 2:" <bload 2: "<bload 2:" upload 2: "upload 2:" upload 2: name = "file2"> <br/> <input type = "Отправить" value = "opper"> </form>HTTP -пакет захват
Попробуйте получить данные с помощью getParameter () на сервисе
String ss = request.getParameter ("username"); System.out.println (ss);Вы не можете получить данные, напрямую с помощью GetParameter.
Так что мы должны делать? ? ? ? Объект запроса предоставляет потоку ServletinPutStream для чтения данных нам
Мы пытаемся прочитать файл
ServletInputStream inputStream = request.getInputStream (); байт [] байты = новый байт [1024]; int len = 0; while ((len = inputstream.read (bytes))> 0) {System.out.println (new String (Bytes, 0, Len)); }Добавьте дополнительное управление вводом на страницу JSP
<input type = "text" name = "пароль">
Текстовый файл, который я загрузил, составляет 111111, и эффект чтения выглядит следующим образом:
Теперь мы можем прочитать данные о загрузке файлов, но теперь вопрос в том, как отделить загруженные данные файла от данных, отправленных на сервер? ? ? Мы видели выше на картинке, они смешаны вместе.
Это трудно разделить в соответствии с нашей обычной практикой, поэтому нам нужно загрузить компоненты
Существуют два типа компонентов загрузки файлов [больше операции] samrtupload [больше операции] fileupload
Чтобы использовать компонент FileUpload, вам необходимо импортировать два пакета JAR
Commons-IO Commons-FileUpload Шаги разработки Создать объект Parser Factory [diskFileItemFactory] Создать анализатор через фабрику синтаксического анализатора [ServletFileUpload] Вызовите метод анализатора, чтобы анализировать объект запроса, получить все загруженное содержание [список], пройдя список, определить, является ли каждый объект загруженным файлом. Если это нормальное поле формы, получите имя поля и значение поля. Если это загруженный файл, вызовите метод InputSteam, чтобы получить входной поток, быстро прочтите загруженные данные.
Попробуйте {// 1. Получить фабрику синхронизации DiskFileItemFactory Factory = new DiskFileItemFactory (); // 2. Получить анализатор ServletFileUpload upload = new ServletFileUpload (Factory); // 3. Определите тип формы загрузки if (! Upload.ismultipartContent (request)) {// Загрузить форму - это нормальная форма, затем получить данные традиционным способом возврата; } // Чтобы загрузить форму, вызовите анализатор, чтобы анализировать загруженный список данных <FieleItem> list = upload.parseRequest (request); // FileItem // Переливание списка и получение объекта FileItem, используемого для инкапсуляции объекта первой загрузки ввода, объекта Data FileItem для (FileItem Item: List) {if (item.isformfield ()) {// Что вы получаете, является нормальным элементом ввода nem = item.getfieldname (); // Получить имя значения ввода string string = item.getString (); System.out.println (name + "=" + value); } else {// Получить загрузку элемента ввода string fileName = item.getName (); // Получить имя файла загрузки c:/документы и настройки/thinkpad/desktop/1.txt filename = filename.substring (filename.lastiNdexof ("//")+1); InputStream in = item.getInputStream (); // Получить загрузку данных int len = 0; байтовый буфер [] = новый байт [1024]; String savePath = this.getServletContext (). GetRealPath ("/upload"); FileOutputStream OUT = new FileOutputStream (savePath + "//" + filename); // записать файл в каталог загрузки while ((len = in.read (buffer))> 0) {out.write (buffer, 0, len); } in.close (); out.close (); }}} catch (Exception e) {e.printstackTrace (); }Проверка, что как обычные поля, так и загруженные файлы могут быть прочитаны и получены!
Smartupload
Чтобы использовать компонент Smartupload, вам необходимо импортировать пакет разработки Smartupload.jar
Быстрый старт
// создание компонентов Smartupload SmartUpload = new SmartUpload (); // Инициализировать операцию загрузки smartupload.initialize (this.getServletConfig (), запрос, ответ); try {// загрузить подготовку smartupload.upload (); // Для обычных данных настолько просто, что объект запроса не может получить представленные параметры. Кроме того, вам нужно полагаться на Smartupload String Password = Smartupload.getRequest (). GetParameter ("пароль"); System.out.println (пароль); // загружать в папку uploadfile smartupload.save ("uploadfile"); } catch (smartuploadexception e) {e.printstacktrace (); }тест
Точно так же мы можем загружать файлы в папку uploadfile. Количество кода действительно сильно уменьшено!
Вы также можете получить параметры нормальных полей
Я изменил имя файла на искаженную код Китая и искаженную китайскую код для загрузки данных, и это был искаженный код:
Китайские данные, представленные в форме, также искажены.
Как упомянуто выше, форма загрузки файловых данных инкапсулируется в двоичном файле, поэтому использование запроса для кодирования данных не будет работать для данных, представленных формой!
FileUpload решает искаженную код
Использование FileUpload для решения искаженных задач очень просто
Решите искаженное китайское имя файла. После получения анализатора, просто установите кодирование анализатора UTF-8!
// Установить кодирование upload fileupload.setheaderencoding ("utf-8");Решите данные искаженной формы. При получении значений формы используйте кодирование UTF-8 для их получения.
String value = fileitem.getString ("UTF-8");Эффект:
Smartupload решает искаженную код
Этот компонент немного неприятен для решения проблемы искаженного кода. Я нашел различные решения в Интернете, но не смог найти простой ...
Поэтому, если данные не включают китайский, используйте компонент Smartupload, и если они включают китайские данные, используйте компонент FileUpload!
Загрузите несколько файлов, динамически складывайте элементы управления загрузкой
Предположим, у меня есть несколько файлов для загрузки сейчас, и количество файлов для загрузки неясно. Так что мы должны делать? ? ?
Нам невозможно перечислить много элементов управления для загрузки файлов на странице, что не красиво. Если пользователь не может использовать так много элементов управления, это пустая трата.
Поэтому мы хотим динамически добавить элементы управления для загрузки файлов. Если пользователь также хочет загружать файлы, ему нужно только динамически генерировать элементы управления!
анализировать
Чтобы динамически генерировать элементы управления на странице, это не что иное, как использование кода JavaScript.
Так что нам делать? ?
Давайте сделаем это: когда пользователь хочет загрузить файл, нажмите кнопку, и кнопка связывает событие, чтобы сгенерировать элемент управления для загрузки файла.
Чтобы сделать более идеально, всякий раз, когда генерируется управление загрузкой файла, также предоставляется кнопка удаления для удаления элемента управления!
Мы должны использовать Div для загрузки элементов управления и удаления кнопок, которые мы хотим генерировать. Когда пользователь нажимает, чтобы удалить, он должен скрыть кнопку Delete и управлять загрузкой файлов вместе. Итак, лучше всего использовать вложенные DOV!
Код кодовой страницы:
<table> <tr> <td>Upload user: </td> <td><input type="text" name="username"></td> </tr> <tr> <td>Add upload file</td> <td><input type="button" value="Add upload file"> </td> </tr> <tr> <td> <div> </div> </td> </td> </tr> </table>
код JavaScript
<script type = "text/javascript"> function addUploadFile () {// генерировать управление загрузкой файла var input = document.createElement ("input"); input.type = 'file'; input.name = 'filename'; // генерировать кнопку удаления var del = document.createElement ("input"); del.type = 'button'; del.value = 'delete'; // генерировать внутренний div var innerdiv = document.createElement ("div"); // связывать два элемента управления с innerdiv.appendchild (input); innerdiv.appendchild (del); // Получить управление внешним div и связывать внутренний Div с внешним div var outterdiv = document.getelementbyid ("file"); outterdiv.appendchild (innerdiv); // Связывать событие del.onclick = function delete () {// вызов метода удаления внешнего DIV, чтобы убить внутренний div this.parentnode.parentnode.removechild (this.parentnode); }} </script>Загрузка файла. Если размер загруженного файла больше, чем размер установленного файла, то файл будет использовать временный файл для сохранения загруженных данных при загрузке. После загрузки мы должны удалить временный файл. Местоположение, в котором файл загрузки не может быть управляется веб -сервером, в противном случае он может вызвать проблемы безопасности [другие могут изменить файл загрузки через средства] Если имя файла загрузки одинаково, исходный файл загрузки будет перезаписан. Мы хотим генерировать уникальное имя файла. Если количество пользователей большое, загружено много файлов. Затем мы не должны сохранять все файлы загрузки в одном каталоге, что, вероятно, приведет к сбою диска. Таким образом, мы должны рассеять загруженные файлы в разные каталоги. анализировать
Проблема удаления временных файлов очень проста. Вам нужно только вызвать метод delete () FileItem после завершения всех операций.
Чтобы предотвратить управление загруженным файлом на веб-сервере, мы можем просто поместить загруженное местоположение файла в каталог Web-Inf/!
Для того же имени файла мы можем использовать имя файла uuid+, загруженное пользователем в качестве наше загруженное имя файла. Такое имя файла уникально.
Чтобы разбить загруженные файлы, нам нужно использовать алгоритм хэшкодов для расставания.
Нижние четыре бита генерируют каталог первого уровня 5-8 бит. Создание кода каталога второго уровня
Давайте напишем относительно полный код файла загрузки
Использовать алгоритм хэшкодов для разрыва сохраненных каталогов
Private String MADEDIRPATH (String FileName, String Path) {// Рассчитайте первичные и вторичные каталоги через имя файла int hashcode = filename.hashcode (); int dir1 = hashcode & 0xf; int dir2 = (hashcode & 0xf0) >> 4; String dir = path + "//" + dir1 + "//" + dir2; // Если каталог не существует, создайте файл файла каталога = новый файл (dir); if (! file.exists ()) {file.mkdirs (); } // возвращать полный путь return dir; }Генерировать уникальные имена файлов
Private String MakeFilename (String FileName) {// Используйте подчеркивание, чтобы отделить UUID и имя файла, и имя файла может быть проанализировано позже. return uuid.randomuuid (). toString () + "_" + файл; }Загруженный код
// Создать Factory DiskFileItemFactory Factory = new DiskFileItemFactory (); // Создать анализатор через заводской сервисфейл -файл fileUpload = new ServletFileUpload (Factory); // Установить код upload fileupload.setheaderencoding ("utf-8"); // судить тип формы загрузки if (! Fileupload.ismultipartContent (request)) {// Загрузить форму как обычную форму, затем получить данные традиционным способом возврата; } try {// packse объект запроса, чтобы получить список [загрузить все загруженное контент] list <fieTiTem> list = fileUpload.parseRequest (request); // Путешествие через список, чтобы определить, является ли загруженное содержимое нормальным полем или файлом загрузки для (fileitem fileitem: list) {// Если это обычный элемент ввода if (fileitem.isformfield ()) {// Получить имя и значение вводного элемента name = fileitem.getfieldname (); String value = fileitem.getString ("UTF-8"); System.out.println (name + "=" + value); } else {// Если это файл загрузки // Получить имя загрузки [включая имя пути] string fileName = fileitem.getName (); // перехватить имя файла filename = filename.substring (fileName.lastIndexof ("//") + 1); // генерировать уникальное имя файла fileName = MakeFilename (имя файла); InputStream inputStream = fileitem.getInputStream (); // Получить путь проекта и написать загруженный файл в Project String Path = this.getServletContext (). GetRealPath ("/web-inf/uploadfile"); // Получить разбросанный путь каталога string realpath = madedirpath (имя файла, path); FileOutputStream outputStream = new FileOutputStream (realPath + "//" + filename); байт [] байты = новый байт [1024]; int len = 0; while ((len = inputstream.read (bytes))> 0) {outputstream.write (bytes, 0, len); } inputStream.close (); outputStream.close (); // удалить данные временного файла fileitem.delete (); }}} catch (fileuploadexception e) {e.printstacktrace (); }Эффект: каталог был успешно разбит, и имя файла было уникальным.
Перечислите файлы в загруженном каталоге и предоставьте загрузки
При объяснении объекта Spose, загрузка файла была объяснена. На этот раз мы напишем небольшой корпус для консолидации загрузки файла.
В каталоге загрузки 3 файла
анализировать
Во -первых, перечислите все файлы в каталоге. Поскольку нам нужно загрузить файл в соответствии с именем файла позже, мы используем коллекцию карт, чтобы сохранить все файлы
Часть загрузки также очень проста. Найдите соответствующий файл в соответствии с именем файла и расположением файла загрузки, прочтите и напишите его, а затем измените заголовок сообщения для достижения загрузки.
Получите путь для загрузки и загрузки файлов, выясните все файлы путем рекурсивно (оценивая, является ли он файлом или является рекурсивным выходом), загрузите его в коллекцию карт и передайте коллекцию карт на стойку регистрации, чтобы отобразить, когда пользователь нажимает, чтобы загрузить, а затем получить абсолютный путь в соответствии с исходным именем. Если ресурс существует, пользователю разрешено загружать код и размещать все файлы, хранящиеся в Web-Inf/ Directory в коллекции карт.
Protected void Dopost (httpservlectrequest, httpservletresponse response) бросает ServletException, ioException {// Получить каталог, в котором загруженный файл-string filePath = this.getServletContext (). getRealPath («/web-inf/upload-knee»); Карта карта = new hashmap (); // Использование рекурсии, чтобы получить все файлы и добавить их в коллекцию карт Getallfiles (новый файл (filePath), Map); request.setattribute ("map", map); request.getRequestDispatcher ("/listfile.jsp"). } private void getallfiles (file filePath, Map Map) {// Если это не файл, то это папка if (! filePath.isfile ()) {// Перечислите все файлы в папке (может быть, файл, может быть, в папке) файл [] files = filePath.listfiles (); для (файл файла: файлы) {// судить о полученном файле (или папке) и getallfiles (file, map); }} else {// Введите оператор ELSE, это должен быть файл // Получить имя файла string fileName = filePath.getName (). substring (filePath.getName (). LastIndexof ("_") + 1); // Мы сохраняем полное имя файла в качестве ключа и имя файла в качестве значения в карте коллекции. }}Показать загружаемые файлы на странице JSP
<C: foreach elects = "$ {map}" var = "me"> <c: url var = "url" value = "/downfileservlet"> <c: param name = "filename" value = "$ {me.key}"> </c: param> </c: url> $ {me.value} <href = "$ {url {url>" me.value} <href = "$ {url" = "rel" = "relower" = "ullok" = "ullok"! </a> <br> </c: Foreach>Реализуйте загруженный сервлет
Protected void Dopost (httpservlectrequest, httpservletresponse response) Throws servletexception, ioexception {// Получить полное имя файлового файла string = request.getParameter ("filename"); // Если это китайские данные, требуется транскодирование. fileName = new String (fileName.getBytes ("iso8859-1"), "UTF-8"); // Получить местоположение, в котором файл сохраняется string path = this.getServletContext (). GetRealPath ("/web-inf/uploadfile"); // Файл сохраняется через имя файла с помощью HashCode, и файл получает через имя файла string fileerealPath = makeFilePath (имя файла, path); System.out.println (FileRealPath); // Судят, существует ли файл файл файла = новый файл (fileerealPath); if (! file.exists ()) {request.setattribute ("Сообщение", "Ресурс, который вы хотите загрузить, не существует!"); request.getRequestDispatcher ("/message.jsp"). возвращаться ; } // Существуют // Прочитайте файл и запишите данные в браузер FileInputStream inputStream = new FileInputStream (FileRealPath); байт [] байты = новый байт [1024]; int len = 0; while ((len = inputstream.read (bytes))> 0) {response.getOutputStream (). write (bytes, 0, len); } inputStream.close (); // Установить заголовок сообщения, чтобы сообщить браузеру, что это загруженное имя строки файла = filename.substring (fileName.lastIndexof ("_") + 1); response.setheader ("Содержимое-распада", "ATTHAMENT; FILENAME =" + urlencoder.encode (имя, "UTF-8")); } частная строка MakeFilePath (String Filename, String Path) {int hashcode = filename.hashcode (); int dir1 = hashcode & 0xf; int dir2 = (hashcode & 0xf0) >> 4; String dir = path + "//" + dir1 + "//" + dir2 + "//" + filename; возврат режира; }Эффект
Если в статье есть какие -либо ошибки, поправьте меня, и все будут общаться друг с другом. Спасибо за поддержку Wulin.com.