Wie kann ich Dateien mit JSP / Servlet auf den Server hochladen? Ich habe es versucht:
<form action="upload" method="post">
<input type="text" name="description" />
<input type="file" name="file" />
<input type="submit" />
</form>
Ich erhalte jedoch nur den Dateinamen, nicht den Dateiinhalt. Als ich hinzufügen , enctype="multipart/form-data"
auf die <form>
dann request.getParameter()
zurückkehrt null
.
Während der Recherche bin ich auf Apache Common FileUpload gestoßen . Ich habe es versucht:
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List items = upload.parseRequest(request); // This line is where it died.
Leider hat das Servlet eine Ausnahme ohne eindeutige Meldung und Ursache ausgelöst. Hier ist die Stapelverfolgung:
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
Thang Pham
quelle
quelle
Antworten:
Einführung
Zum Durchsuchen und Auswählen einer Datei zum Hochladen benötigen Sie ein HTML-
<input type="file">
Feld im Formular. Wie in der HTML-Spezifikation angegeben , müssen Sie diePOST
Methode verwenden und dasenctype
Attribut des Formulars muss festgelegt werden"multipart/form-data"
.Nach dem Absenden eines solchen Formulars stehen die binären mehrteiligen Formulardaten im Anforderungshauptteil in einem anderen Format zur Verfügung als beim
enctype
nicht festgelegt ist.Vor Servlet 3.0 wurde die Servlet-API von Haus aus nicht unterstützt
multipart/form-data
. Es wird nur der Standardformular-Enctype von unterstütztapplication/x-www-form-urlencoded
. Dierequest.getParameter()
und -Konsorten würden alle zurückkehren,null
wenn mehrteilige Formulardaten verwendet werden. Hier befindet sich der bekannte Apache Commons FileUpload ins .Analysieren Sie es nicht manuell!
Sie können den Anfragetext theoretisch selbst anhand von analysieren
ServletRequest#getInputStream()
. Dies ist jedoch eine präzise und langwierige Arbeit, die genaue Kenntnisse von RFC2388 erfordert . Sie sollten nicht versuchen, dies selbst zu tun oder einen selbst entwickelten Code ohne Bibliothek zu kopieren, der an anderer Stelle im Internet zu finden ist. Viele Online-Quellen wie roseindia.net sind dabei schwer gescheitert. Siehe auch Hochladen der PDF-Datei . Sie sollten lieber eine echte Bibliothek verwenden, die jahrelang von Millionen von Benutzern verwendet (und implizit getestet!) Wird. Eine solche Bibliothek hat ihre Robustheit bewiesen.Wenn Sie bereits Servlet 3.0 oder höher verwenden, verwenden Sie die native API
Wenn Sie mindestens Servlet 3.0 verwenden (Tomcat 7, Jetty 9, JBoss AS 6, GlassFish 3 usw.), können Sie einfach die bereitgestellte Standard-API verwenden
HttpServletRequest#getPart()
, um die einzelnen mehrteiligen Formulardatenelemente zu erfassen (die meisten Servlet 3.0-Implementierungen verwenden tatsächlich Apache Commons FileUpload unter der Decke dafür!). Außerdem sind normale Formularfelder aufgetParameter()
die übliche Weise verfügbar .Kommentieren Sie zuerst Ihr Servlet mit
@MultipartConfig
, damit esmultipart/form-data
Anforderungen erkennt und unterstützt und somitgetPart()
an die Arbeit geht:Implementieren Sie dann
doPost()
Folgendes:Beachten Sie die
Path#getFileName()
. Dies ist ein MSIE-Fix zum Abrufen des Dateinamens. Dieser Browser sendet fälschlicherweise den vollständigen Dateipfad entlang des Namens anstelle nur des Dateinamens.Wenn Sie einen
<input type="file" name="file" multiple="true" />
Upload für mehrere Dateien haben, sammeln Sie diese wie folgt (leider gibt es keine Methode wierequest.getParts("file")
):Wenn Sie noch nicht mit Servlet 3.1 arbeiten, rufen Sie den übermittelten Dateinamen manuell ab
Beachten Sie, dass dies
Part#getSubmittedFileName()
in Servlet 3.1 eingeführt wurde (Tomcat 8, Jetty 9, WildFly 8, GlassFish 4 usw.). Wenn Sie noch nicht mit Servlet 3.1 arbeiten, benötigen Sie eine zusätzliche Dienstprogrammmethode, um den übermittelten Dateinamen abzurufen.Beachten Sie den MSIE-Fix zum Abrufen des Dateinamens. Dieser Browser sendet fälschlicherweise den vollständigen Dateipfad entlang des Namens anstelle nur des Dateinamens.
Wenn Sie noch nicht mit Servlet 3.0 arbeiten, verwenden Sie Apache Commons FileUpload
Wenn Sie noch nicht mit Servlet 3.0 arbeiten (ist es nicht an der Zeit, ein Upgrade durchzuführen ?), Wird in der Regel Apache Commons FileUpload verwendet , um die mehrteiligen Formulardatenanforderungen zu analysieren. Es hat eine ausgezeichnete Bedienungsanleitung und FAQ (gehen Sie beide sorgfältig durch). Es gibt auch den O'Reilly (" cos ")
MultipartRequest
, aber er hat einige (kleinere) Fehler und wird seit Jahren nicht mehr aktiv gewartet. Ich würde es nicht empfehlen. Apache Commons FileUpload wird immer noch aktiv gepflegt und ist derzeit sehr ausgereift.Um Apache Commons FileUpload verwenden zu können, müssen mindestens die folgenden Dateien in Ihrer Webanwendung enthalten sein
/WEB-INF/lib
:commons-fileupload.jar
commons-io.jar
Ihr erster Versuch ist höchstwahrscheinlich fehlgeschlagen, weil Sie die Commons-E / A vergessen haben.
Hier ist ein Kickoff-Beispiel, wie das
doPost()
von IhnenUploadServlet
aussehen könnte, wenn Sie Apache Commons FileUpload verwenden:Es ist sehr wichtig , dass Sie nicht nennen
getParameter()
,getParameterMap()
,getParameterValues()
,getInputStream()
,getReader()
, usw. auf den gleichen Antrag zuvor. Andernfalls liest und analysiert der Servlet-Container den Anforderungshauptteil, sodass Apache Commons FileUpload einen leeren Anforderungshauptteil erhält. Siehe auch ao ServletFileUpload # parseRequest (Anfrage) gibt eine leere Liste zurück .Beachten Sie die
FilenameUtils#getName()
. Dies ist ein MSIE-Fix zum Abrufen des Dateinamens. Dieser Browser sendet fälschlicherweise den vollständigen Dateipfad entlang des Namens anstelle nur des Dateinamens.Alternativ können Sie dies alles auch in eine
Filter
Datei packen, die alles automatisch analysiert und das Material wieder in die Parameterkarte der Anforderung einfügt, sodass Sie aufrequest.getParameter()
die übliche Weise fortfahren und die hochgeladene Datei von abrufen könnenrequest.getAttribute()
. Ein Beispiel finden Sie in diesem Blog-Artikel .Problemumgehung für den GlassFish3-Fehler,
getParameter()
immer noch zurückzukehrennull
Beachten Sie, dass Glassfish-Versionen älter als 3.1.2 einen Fehler hatten, bei dem das
getParameter()
immer noch zurückkehrtnull
. Wenn Sie auf einen solchen Container abzielen und ihn nicht aktualisieren können, müssen Sie den WertgetPart()
mithilfe dieser Dienstprogrammmethode extrahieren :Hochgeladene Datei speichern (weder verwenden
getRealPath()
nochpart.write()
!)Weitere Informationen zum ordnungsgemäßen Speichern der erhaltenen
InputStream
(derfileContent
in den obigen Codeausschnitten gezeigten Variablen) auf Festplatte oder Datenbank finden Sie in den folgenden Antworten :Hochgeladene Datei bereitstellen
Weitere Informationen zum ordnungsgemäßen Bereitstellen der gespeicherten Datei von der Festplatte oder Datenbank auf dem Client finden Sie in den folgenden Antworten:
Ajaxifizierung der Form
Lesen Sie die folgenden Antworten zum Hochladen mit Ajax (und jQuery). Beachten Sie, dass der Servlet-Code zum Sammeln der Formulardaten dafür nicht geändert werden muss! Nur die Art und Weise, wie Sie reagieren, kann geändert werden. Dies ist jedoch eher trivial (dh anstatt an JSP weiterzuleiten, drucken Sie einfach JSON oder XML oder sogar einfachen Text, je nachdem, was das für den Ajax-Aufruf verantwortliche Skript erwartet).
Hoffe das alles hilft :)
quelle
request.getParts("file")
und war verwirrt x_xMultipartConfig
Bedingung verletzt wird (z. B. :)maxFileSize
, gibt der Aufrufrequest.getParameter()
null zurück. Ist das absichtlich? Was ist, wenn ich vor dem AufrufgetPart
(und der Suche nach einemIllegalStateException
) einige reguläre (Text-) Parameter erhalte ? Dies führtNullPointerException
dazu, dass ein geworfen wird, bevor ich die Möglichkeit habe, nach dem zu suchenIllegalStateException
.String fileName = Paths.get(filePart.getSubmittedFileName()).getFileName().toString(); // MSIE fix.
er auf ein ähnliches ProblemWenn Sie Spring MVC verwenden, gehen Sie wie folgt vor: (Ich lasse dies hier, falls jemand es nützlich findet.)
Verwenden Sie ein Formular mit dem
enctype
Attribut "multipart/form-data
" (wie die Antwort von BalusC).In Ihrem Controller, ordnen Sie die Anfrageparameter
file
zuMultipartFile
Typ wie folgt:Sie können den Dateinamen und die Größe mit
MultipartFile
'sgetOriginalFilename()
und erhaltengetSize()
.Ich habe dies mit der Spring-Version getestet
4.1.1.RELEASE
.quelle
Sie müssen die
common-io.1.4.jar
Datei in Ihrlib
Verzeichnis aufnehmen, oder wenn Sie in einem Editor wie NetBeans arbeiten, müssen Sie zu den Projekteigenschaften gehen und einfach die JAR-Datei hinzufügen, und fertig.Um die
common.io.jar
Datei zu erhalten, googeln Sie sie einfach oder besuchen Sie die Apache Tomcat- Website, auf der Sie die Option zum kostenlosen Download dieser Datei erhalten. Beachten Sie jedoch Folgendes: Laden Sie die binäre ZIP-Datei herunter, wenn Sie Windows verwenden.quelle
.jar
aber.zip
. Meinst du.zip
?Ohne Komponente oder externe Bibliothek in Tomcat 6 o 7
Aktivieren des Uploads in der Datei web.xml :
http://joseluisbz.wordpress.com/2014/01/17/manuell-installing-php-tomcat-and-httpd-lounge/#Enabling%20File%20Uploads .
WIE SIE SEHEN KÖNNEN :
Hochladen von Dateien mit JSP. Dateien:
In der HTML-Datei
In der JSP-Datei oder im Servlet
Bearbeiten Sie Ihren Code an die Servlet-Anforderungen wie maximale Dateigröße , maximale Anforderungsgröße und andere Optionen, die Sie festlegen können ...
quelle
Ich verwende ein gemeinsames Servlet für jedes HTML-Formular, unabhängig davon, ob es Anhänge enthält oder nicht. Dieses Servlet gibt a zurück,
TreeMap
wobei die Schlüssel jsp name sind. Parameter und Werte sind Benutzereingaben und speichert alle Anhänge im festen Verzeichnis. Später benennen Sie das Verzeichnis Ihrer Wahl um. Hier ist Connections unsere benutzerdefinierte Schnittstelle mit Verbindungsobjekt. Ich denke, das wird dir helfenquelle
Für Spring MVC habe ich stundenlang versucht, dies zu tun, und es ist mir gelungen, eine einfachere Version zu haben, die sowohl für die Eingabe von Daten als auch für Bilder geeignet ist.
Controller zu handhaben
Ich hoffe es hilft :)
quelle
Eine weitere Ursache für dieses Problem tritt auf, wenn Sie Geronimo mit seinem eingebetteten Tomcat verwenden. In diesem Fall tritt das Problem nach vielen Iterationen des Testens von commons-io und commons-fileupload von einem übergeordneten Klassenladeprogramm auf, das die commons-xxx-Jars verarbeitet. Dies muss verhindert werden. Der Absturz ereignete sich immer um:
Beachten Sie, dass sich der Listentyp von fileItems mit der aktuellen Version von commons-fileupload geändert hat, um
List<FileItem>
im Gegensatz zu früheren Versionen, in denen es generisch war , spezifisch zu seinList
.Ich habe den Quellcode für commons-fileupload und commons-io in mein Eclipse-Projekt eingefügt, um den tatsächlichen Fehler zu verfolgen, und schließlich einen Einblick erhalten. Erstens ist die ausgelöste Ausnahme vom Typ Throwable, nicht die angegebene FileIOException oder sogar Exception (diese werden nicht abgefangen). Zweitens ist die Fehlermeldung insofern verschleiert, als sie angibt, dass die Klasse nicht gefunden wurde, weil axis2 commons-io nicht finden konnte. Axis2 wird in meinem Projekt überhaupt nicht verwendet, ist jedoch im Rahmen der Standardinstallation als Ordner im Geronimo-Repository-Unterverzeichnis vorhanden.
Schließlich fand ich einen Ort, der eine funktionierende Lösung darstellte, die mein Problem erfolgreich löste. Sie müssen die Jars vor dem übergeordneten Loader im Bereitstellungsplan ausblenden. Dies wurde in geronimo-web.xml mit meiner vollständigen Datei unten gezeigt.
quelle
Hier ist ein Beispiel mit Apache Commons-Fileupload:
quelle
Der einfachste Weg für Dateien und Eingabesteuerungen ohne eine Milliarde Bibliotheken:
quelle
Sie können Dateien mit jsp / servlet hochladen.
auf der anderen Seite Server-Seite. Verwenden Sie den folgenden Code.
quelle
Von diesem Objekt müssen Sie Dateielemente und Felder abrufen, die Sie dann wie folgt auf dem Server speichern können:
quelle
Senden mehrerer Dateien für Dateien, die wir verwenden müssen,
enctype="multipart/form-data"
und Senden mehrerer Dateien
multiple="multiple"
im Eingabe-Tagquelle
HTML-SEITE
SERVLET-DATEI
web.xml
Kompilieren Sie das obige Servlet UploadServlet und erstellen Sie den erforderlichen Eintrag in der Datei web.xml wie folgt.
quelle