Как я могу загрузить файлы на сервер, используя JSP / Servlet? Я попробовал это:
<form action="upload" method="post">
<input type="text" name="description" />
<input type="file" name="file" />
<input type="submit" />
</form>
Однако я получаю только имя файла, а не содержимое файла. Когда я добавляю enctype="multipart/form-data"
к <form>
, то request.getParameter()
возвращаетnull
.
Во время исследования я наткнулся на Apache Common FileUpload . Я попробовал это:
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List items = upload.parseRequest(request); // This line is where it died.
К сожалению, сервлет выдал исключение без четкого сообщения и причины. Вот трассировка стека:
SEVERE: Servlet.service() for servlet UploadServlet threw exception
javax.servlet.ServletException: Servlet execution threw an exception
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:313)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:637)
java
jsp
jakarta-ee
servlets
file-upload
Тханг Фам
источник
источник
Ответы:
Введение
Для просмотра и выбора файла для загрузки вам нужно
<input type="file">
поле HTML в форме. Как указано в спецификации HTML, вы должны использоватьPOST
метод, аenctype
атрибут формы должен быть установлен в"multipart/form-data"
.После отправки такой формы двоичные данные многочастной формы доступны в теле запроса в другом формате, чем когда
enctype
не задано.До Servlet 3.0 API Servlet изначально не поддерживался
multipart/form-data
. Он поддерживает только тип формы по умолчаниюapplication/x-www-form-urlencoded
. Всеrequest.getParameter()
операторы and возвращаютсяnull
при использовании данных многоэлементной формы. Вот тут-то и появилась хорошо известная Apache Commons FileUpload .Не разбирайте его вручную!
Теоретически вы можете самостоятельно проанализировать тело запроса
ServletRequest#getInputStream()
. Тем не менее, это точная и утомительная работа, которая требует точного знания RFC2388 . Вы не должны пытаться сделать это самостоятельно или скопировать какой-нибудь домашний безбиблиотечный код, найденный в другом месте в Интернете. Многие интернет-источники сильно пострадали в этом, например roseindia.net. Смотрите также загрузка файла PDF . Вы должны использовать реальную библиотеку, которая используется (и неявно проверяется!) Миллионами пользователей годами. Такая библиотека доказала свою надежность.Если вы уже используете Servlet 3.0 или новее, используйте собственный API
Если вы используете хотя бы Servlet 3.0 (Tomcat 7, Jetty 9, JBoss AS 6, GlassFish 3 и т. Д.), То вы можете просто использовать стандартный API, предоставленный
HttpServletRequest#getPart()
для сбора отдельных элементов данных многоэлементной формы (большинство реализаций Servlet 3.0 фактически используют Apache Commons FileUpload под чехлы для этого!). Также обычные поля формы доступныgetParameter()
обычным способом.Сначала аннотируйте ваш сервлет
@MultipartConfig
, чтобы он мог распознавать и поддерживатьmultipart/form-data
запросы и, таким образом, приступатьgetPart()
к работе:Затем выполните его
doPost()
следующим образом:Обратите внимание
Path#getFileName()
. Это исправление MSIE для получения имени файла. Этот браузер неправильно отправляет полный путь к файлу вдоль имени, а не только имя файла.Если у вас есть возможность
<input type="file" name="file" multiple="true" />
загрузки нескольких файлов, соберите их, как показано ниже (к сожалению, такого метода нетrequest.getParts("file")
):Если вы еще не используете Servlet 3.1, вручную введите имя файла
Обратите внимание, что это
Part#getSubmittedFileName()
было введено в Servlet 3.1 (Tomcat 8, Jetty 9, WildFly 8, GlassFish 4 и т. Д.). Если вы еще не используете Servlet 3.1, вам нужен дополнительный метод для получения имени отправленного файла.Обратите внимание на исправление MSIE относительно получения имени файла. Этот браузер неправильно отправляет полный путь к файлу вдоль имени, а не только имя файла.
Если вы еще не используете Servlet 3.0, используйте Apache Commons FileUpload
Если вы еще не используете Servlet 3.0 (не пора ли обновиться?), Обычной практикой является использование Apache Commons FileUpload для анализа запросов данных из нескольких частей. Он имеет отличное руководство пользователя и часто задаваемые вопросы (внимательно просмотрите оба). Есть также O'Reilly (" cos ")
MultipartRequest
, но он имеет некоторые (незначительные) ошибки и больше не поддерживается в течение многих лет. Я не рекомендовал бы использовать это. Apache Commons FileUpload все еще активно поддерживается и в настоящее время очень зрелый.Чтобы использовать Apache Commons FileUpload, в вашем веб-приложении должны быть как минимум следующие файлы
/WEB-INF/lib
:commons-fileupload.jar
commons-io.jar
Ваша первоначальная попытка, скорее всего, не удалась, потому что вы забыли общий ввод-вывод.
Вот пример того, как
doPost()
выUploadServlet
можете выглядеть при использовании Apache Commons FileUpload:Это очень важно , чтобы вы не вызываете
getParameter()
,getParameterMap()
,getParameterValues()
,getInputStream()
,getReader()
, и т.д. на тот же запрос заранее. В противном случае контейнер сервлета будет читать и анализировать тело запроса, и, следовательно, Apache Commons FileUpload получит пустое тело запроса. Смотрите также. ServletFileUpload # parseRequest (запрос) возвращает пустой список .Обратите внимание
FilenameUtils#getName()
. Это исправление MSIE для получения имени файла. Этот браузер неправильно отправляет полный путь к файлу вдоль имени, а не только имя файла.В качестве альтернативы вы можете также обернуть все это в
Filter
файл, который автоматически анализирует все это, и поместить его обратно в карту параметров запроса, чтобы вы могли продолжить использоватьrequest.getParameter()
обычный способ и получить загруженный файлrequest.getAttribute()
. Вы можете найти пример в этой статье блога .Обходной путь для ошибки GlassFish3 по-
getParameter()
прежнему возвращаетсяnull
Обратите внимание, что в версиях Glassfish, более старых, чем 3.1.2, была ошибка, при которой они
getParameter()
все еще возвращалисьnull
. Если вы нацеливаетесь на такой контейнер и не можете обновить его, вам нужно извлечь значениеgetPart()
с помощью этого служебного метода:Сохранение загруженного файла (не используйте
getRealPath()
ниpart.write()
!)Перейдите к следующим ответам для получения подробной информации о правильном сохранении полученного
InputStream
(fileContent
переменная, как показано в приведенных выше фрагментах кода) на диск или в базу данных:Обслуживание загруженного файла
Обратитесь к следующим ответам для получения подробной информации о правильной доставке сохраненного файла с диска или базы данных обратно клиенту:
Аяксификация формы
Перейдите к следующим ответам, как загрузить с помощью Ajax (и jQuery). Обратите внимание, что код сервлета для сбора данных формы не нужно менять для этого! Может быть изменено только то, как вы отвечаете, но это довольно тривиально (т.е. вместо пересылки в JSP просто напечатайте JSON или XML или даже простой текст в зависимости от того, что ожидает скрипт, ответственный за вызов Ajax).
Надеюсь, это все помогает :)
источник
request.getParts("file")
и был смущен x_xMultipartConfig
условие нарушено (например:)maxFileSize
, вызовrequest.getParameter()
возвращает null. Это специально? Что если я получу некоторые обычные (текстовые) параметры перед вызовомgetPart
(и проверкой на наличиеIllegalStateException
)? Это заставляетNullPointerException
быть брошенным прежде, чем у меня есть шанс проверитьIllegalStateException
.String fileName = Paths.get(filePart.getSubmittedFileName()).getFileName().toString(); // MSIE fix.
отчасти похожей на меняЕсли вы используете Spring MVC, вот как это сделать: (Я оставляю это здесь на случай, если кто-то посчитает это полезным).
Используйте форму с
enctype
атрибутом, установленным на "multipart/form-data
" (такой же, как в ответе BalusC)В вашем контроллере сопоставьте параметр запроса
file
соMultipartFile
следующим:Вы можете получить имя файла и размер, используя
MultipartFile
sgetOriginalFilename()
иgetSize()
.Я проверил это с версией Spring
4.1.1.RELEASE
.источник
Вам нужно, чтобы
common-io.1.4.jar
файл был включен в вашlib
каталог, или если вы работаете в каком-либо редакторе, например NetBeans, вам нужно перейти к свойствам проекта и просто добавить файл JAR, и все готово.Чтобы получить
common.io.jar
файл, просто зайдите в него или перейдите на веб-сайт Apache Tomcat, где вы можете бесплатно загрузить этот файл. Но помните одно: скачайте бинарный ZIP-файл, если вы пользователь Windows.источник
.jar
но.zip
. Вы имеете в виду.zip
?Без компонента или внешней библиотеки в Tomcat 6 o 7
Включение загрузки в файле web.xml :
http://joseluisbz.wordpress.com/2014/01/17/manually-install-php-tomcat-and-httpd-lounge/#Enabling%20File%20Uploads .
КАК ВЫ МОЖЕТЕ УВИДЕТЬ :
Загрузка файлов с использованием JSP. файлы:
В HTML-файл
В файле JSP или сервлете
Измените свой код в соответствии с требованиями сервлета, такими как максимальный размер файла , максимальный размер запроса и другие параметры, которые вы можете установить ...
источник
Я использую общий сервлет для каждой HTML-формы, имеет ли она вложения или нет. Этот сервлет возвращает a,
TreeMap
где ключами являются jsp name. Параметры и значения - это пользовательские входы и сохраняет все вложения в фиксированном каталоге, а затем вы переименовываете каталог по вашему выбору. Здесь Connections - наш пользовательский интерфейс, имеющий объект подключения. Я думаю, что это поможет вамисточник
Для Spring MVC я часами пытался сделать это, и мне удалось получить более простую версию, которая работала бы для ввода формы и данных, и изображений.
Контроллер для обработки
Надеюсь, поможет :)
источник
Другой источник этой проблемы возникает, если вы используете Geronimo со встроенным Tomcat. В этом случае, после многих итераций тестирования commons-io и commons-fileupload, проблема возникает из-за того, что родительский загрузчик классов обрабатывает jars commons-xxx. Это должно быть предотвращено. Авария всегда происходила в:
Обратите внимание, что тип списка fileItems изменился с текущей версией commons-fileupload, чтобы быть
List<FileItem>
в отличие от предыдущих версий, где он был универсальнымList
.Я добавил исходный код для commons-fileupload и commons-io в свой проект Eclipse, чтобы отследить фактическую ошибку, и наконец получил некоторое представление. Во-первых, выброшенное исключение имеет тип Throwable, а не указанное FileIOException или даже Exception (они не будут перехвачены). Во-вторых, сообщение об ошибке запутанно, поскольку в нем указано, что класс не найден, поскольку axis2 не может найти commons-io. Axis2 вообще не используется в моем проекте, но существует как папка в подкаталоге репозитория Geronimo как часть стандартной установки.
Наконец, я нашел 1 место, где было рабочее решение, которое успешно решило мою проблему. Вы должны скрыть банки от родительского загрузчика в плане развертывания. Это было помещено в geronimo-web.xml с моим полным файлом, показанным ниже.
источник
Вот пример использования apache commons-fileupload:
источник
Проще всего было бы придумать для файлов и элементов управления вводом, без миллиарда библиотек:
источник
Вы можете загрузить файл с помощью jsp / servlet.
с другой стороны, на стороне сервера. используйте следующий код.
источник
Из этого объекта вы должны получить элементы файла и поля, после чего вы можете сохранить их на сервере следующим образом:
источник
Отправка нескольких файлов для файла, который мы должны использовать,
enctype="multipart/form-data"
и для отправки нескольких файлов использовать
multiple="multiple"
во входном тегеисточник
HTML PAGE
Файл сервлета
web.xml
Скомпилируйте вышеприведенный сервлет UploadServlet и создайте необходимую запись в файле web.xml следующим образом.
источник