Comment puis-je télécharger des fichiers sur le serveur à l'aide de JSP / Servlet? J'ai essayé ceci:
<form action="upload" method="post">
<input type="text" name="description" />
<input type="file" name="file" />
<input type="submit" />
</form>
Cependant, je ne reçois que le nom du fichier, pas le contenu du fichier. Lorsque j'ajoute enctype="multipart/form-data"
à la <form>
, puis request.getParameter()
revient null
.
Pendant les recherches, je suis tombé sur Apache Common FileUpload . J'ai essayé ceci:
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
List items = upload.parseRequest(request); // This line is where it died.
Malheureusement, le servlet a levé une exception sans message clair ni cause. Voici le stacktrace:
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
la source
la source
Réponses:
introduction
Pour parcourir et sélectionner un fichier à télécharger, vous avez besoin d'un
<input type="file">
champ HTML dans le formulaire. Comme indiqué dans la spécification HTML, vous devez utiliser laPOST
méthode et l'enctype
attribut du formulaire doit être défini sur"multipart/form-data"
.Après avoir soumis un tel formulaire, les données du formulaire binaire en plusieurs parties sont disponibles dans le corps de la demande dans un format différent de celui qui
enctype
n'est pas défini.Avant Servlet 3.0, l'API Servlet ne supportait pas nativement
multipart/form-data
. Il prend uniquement en charge le type de formulaire par défaut deapplication/x-www-form-urlencoded
. Lesrequest.getParameter()
consorts et retourneraient tousnull
lors de l'utilisation de données de formulaire en plusieurs parties. C'est là que le fameux Apache Commons FileUpload est entré en scène.Ne pas analyser manuellement!
Vous pouvez en théorie analyser vous-même le corps de la demande
ServletRequest#getInputStream()
. Cependant, c'est un travail précis et fastidieux qui nécessite une connaissance précise de la RFC2388 . Vous ne devriez pas essayer de le faire par vous-même ou copopastez du code local sans bibliothèque trouvé ailleurs sur Internet. De nombreuses sources en ligne ont échoué dans ce domaine, comme roseindia.net. Voir aussi téléchargement du fichier pdf . Vous devriez plutôt utiliser une vraie bibliothèque qui est utilisée (et implicitement testée!) Par des millions d'utilisateurs pendant des années. Une telle bibliothèque a prouvé sa robustesse.Lorsque vous êtes déjà sur Servlet 3.0 ou plus récent, utilisez l'API native
Si vous utilisez au moins Servlet 3.0 (Tomcat 7, Jetty 9, JBoss AS 6, GlassFish 3, etc.), vous pouvez simplement utiliser l'API standard fournie
HttpServletRequest#getPart()
pour collecter les éléments de données de formulaire multiparties individuels (la plupart des implémentations Servlet 3.0 utilisent réellement Apache Commons FileUpload sous les couvertures pour cela!). De plus, les champs de formulaire normaux sont disponibles degetParameter()
la manière habituelle.Annotez d'abord votre servlet avec
@MultipartConfig
afin de lui permettre de reconnaître et d'accompagner lesmultipart/form-data
requêtes et ainsigetPart()
de travailler:Ensuite, implémentez son
doPost()
comme suit:Notez le
Path#getFileName()
. Il s'agit d'un correctif MSIE quant à l'obtention du nom de fichier. Ce navigateur envoie de façon incorrecte le chemin d'accès complet au fichier au lieu du seul nom de fichier.Dans le cas où vous avez un
<input type="file" name="file" multiple="true" />
téléchargement multi-fichiers, collectez-les comme ci-dessous (malheureusement, il n'existe pas de méthode telle querequest.getParts("file")
):Lorsque vous n'êtes pas encore sur Servlet 3.1, obtenez manuellement le nom du fichier soumis
Notez que cela a
Part#getSubmittedFileName()
été introduit dans Servlet 3.1 (Tomcat 8, Jetty 9, WildFly 8, GlassFish 4, etc.). Si vous n'êtes pas encore sur Servlet 3.1, vous avez besoin d'une méthode utilitaire supplémentaire pour obtenir le nom du fichier soumis.Notez le correctif MSIE quant à l'obtention du nom de fichier. Ce navigateur envoie de façon incorrecte le chemin d'accès complet au fichier au lieu du seul nom de fichier.
Lorsque vous n'êtes pas encore sur Servlet 3.0, utilisez Apache Commons FileUpload
Si vous n'êtes pas encore sur Servlet 3.0 (n'est-il pas temps de mettre à niveau?), La pratique courante consiste à utiliser Apache Commons FileUpload pour analyser les demandes de données de formulaire en plusieurs parties. Il a un excellent guide de l'utilisateur et une FAQ (parcourez attentivement les deux). Il y a aussi le O'Reilly (" cos ")
MultipartRequest
, mais il a quelques bugs (mineurs) et n'est plus activement maintenu depuis des années. Je ne recommanderais pas de l'utiliser. Apache Commons FileUpload est toujours activement maintenu et actuellement très mature.Pour utiliser Apache Commons FileUpload, vous devez avoir au moins les fichiers suivants dans votre application Web
/WEB-INF/lib
:commons-fileupload.jar
commons-io.jar
Votre tentative initiale a échoué très probablement parce que vous avez oublié l'IO commun.
Voici un exemple de lancement à quoi pourrait ressembler
doPost()
votreUploadServlet
lorsque vous utilisez Apache Commons FileUpload:Il est très important que vous ne l' appelez
getParameter()
,getParameterMap()
,getParameterValues()
,getInputStream()
,getReader()
, etc sur la même demande au préalable. Sinon, le conteneur de servlet lira et analysera le corps de la requête et donc Apache Commons FileUpload obtiendra un corps de requête vide. Voir aussi ao ServletFileUpload # parseRequest (request) renvoie une liste vide .Notez le
FilenameUtils#getName()
. Il s'agit d'un correctif MSIE quant à l'obtention du nom de fichier. Ce navigateur envoie de façon incorrecte le chemin d'accès complet au fichier au lieu du seul nom de fichier.Alternativement, vous pouvez également envelopper tout cela dans un
Filter
qui les analyse tous automatiquement et remettre les choses dans le parametermap de la demande afin que vous puissiez continuer à utiliserrequest.getParameter()
la manière habituelle et récupérer le fichier téléchargé parrequest.getAttribute()
. Vous pouvez trouver un exemple dans cet article de blog .Solution de contournement pour le bug GlassFish3 de
getParameter()
retournull
Notez que les versions de Glassfish antérieures à 3.1.2 avaient un bug dans lequel le
getParameter()
retourne toujoursnull
. Si vous ciblez un tel conteneur et ne pouvez pas le mettre à niveau, vous devez extraire la valeurgetPart()
à l'aide de cette méthode utilitaire:Enregistrement du fichier téléchargé (ne pas utiliser
getRealPath()
nipart.write()
!)Consultez les réponses suivantes pour plus de détails sur l'enregistrement correct de la copie obtenue
InputStream
(lafileContent
variable indiquée dans les extraits de code ci-dessus) sur le disque ou la base de données:Servir le fichier téléchargé
Consultez les réponses suivantes pour plus de détails sur la manière de bien servir le fichier enregistré du disque ou de la base de données au client:
Ajaxification du formulaire
Consultez les réponses suivantes pour télécharger à l'aide d'Ajax (et de jQuery). Notez que le code de servlet pour collecter les données du formulaire n'a pas besoin d'être modifié pour cela! Seule la façon dont vous répondez peut être modifiée, mais c'est plutôt trivial (c'est-à-dire qu'au lieu de transférer vers JSP, imprimez simplement du JSON ou du XML ou même du texte brut en fonction de ce que le script responsable de l'appel Ajax attend).
J'espère que tout cela vous aidera :)
la source
request.getParts("file")
et j'étais confus x_xMultipartConfig
condition est violée (par exemplemaxFileSize
:), l'appelrequest.getParameter()
renvoie null. Est-ce exprès? Que faire si j'obtiens des paramètres (texte) normaux avant d'appelergetPart
(et de rechercher unIllegalStateException
)? Cela provoque unNullPointerException
jet avant que je ne puisse vérifier leIllegalStateException
.String fileName = Paths.get(filePart.getSubmittedFileName()).getFileName().toString(); // MSIE fix.
partie similaire à moiS'il vous arrive d'utiliser Spring MVC, voici comment: (Je laisse cela ici au cas où quelqu'un le trouverait utile).
Utilisez un formulaire dont l'
enctype
attribut est défini sur "multipart/form-data
" (identique à la réponse de BalusC)Dans votre contrôleur, mappez le paramètre de demande
file
àMultipartFile
taper comme suit:Vous pouvez obtenir le nom et la taille du fichier en utilisant
MultipartFile
les touchesgetOriginalFilename()
etgetSize()
.J'ai testé cela avec la version Spring
4.1.1.RELEASE
.la source
Vous avez besoin que le
common-io.1.4.jar
fichier soit inclus dans votrelib
répertoire, ou si vous travaillez dans n'importe quel éditeur, comme NetBeans, alors vous devez aller dans les propriétés du projet et ajouter simplement le fichier JAR et vous aurez terminé.Pour obtenir le
common.io.jar
fichier, il suffit de le rechercher sur Google ou simplement de visiter le site Web Apache Tomcat où vous avez la possibilité de télécharger gratuitement ce fichier. Mais souvenez-vous d'une chose: téléchargez le fichier ZIP binaire si vous êtes un utilisateur Windows.la source
.jar
mais.zip
. Tu veux dire.zip
?Sans composant ni bibliothèque externe dans Tomcat 6 o 7
Activation du téléchargement dans le fichier web.xml :
http://joseluisbz.wordpress.com/2014/01/17/manually-installing-php-tomcat-and-httpd-lounge/#Enabling%20File%20Uploads .
COMME VOUS POUVEZ VOIR :
Téléchargement de fichiers à l'aide de JSP. Des dossiers:
Dans le fichier html
Dans le fichier ou le servlet JSP
Modifiez votre code en fonction des exigences de la servlet, comme max-file-size , max-request-size et d'autres options que vous pouvez définir ...
la source
J'utilise un servlet commun pour chaque formulaire HTML, qu'il comporte des pièces jointes ou non. Cette servlet retourne un
TreeMap
où les clés sont le nom jsp Les paramètres et les valeurs sont des entrées utilisateur et enregistre toutes les pièces jointes dans un répertoire fixe et plus tard vous renommez le répertoire de votre choix. Voici les connexions est notre interface personnalisée ayant un objet de connexion. Je crois que ceci vous aiderala source
Pour Spring MVC, j'essaie depuis des heures de le faire et j'ai réussi à avoir une version plus simple qui fonctionnait pour la saisie sous forme de données et d'images.
Contrôleur à gérer
J'espère que cela aide :)
la source
Une autre source de ce problème se produit si vous utilisez Geronimo avec son Tomcat intégré. Dans ce cas, après de nombreuses itérations de test de commons-io et commons-fileupload, le problème provient d'un chargeur de classe parent qui gère les pots communs-xxx. Cela doit être évité. L'accident s'est toujours produit à:
Notez que le type List de fileItems a changé avec la version actuelle de commons-fileupload pour être spécifiquement
List<FileItem>
par opposition aux versions précédentes où il était génériqueList
.J'ai ajouté le code source de commons-fileupload et commons-io dans mon projet Eclipse pour tracer l'erreur réelle et j'ai finalement obtenu un aperçu. Tout d'abord, l'exception levée est de type Throwable, pas l'exception FileIOException indiquée ni même l'exception (celles-ci ne seront pas interceptées). Deuxièmement, le message d'erreur est obscur en ce qu'il indique la classe non trouvée car axis2 n'a pas pu trouver commons-io. Axis2 n'est pas du tout utilisé dans mon projet mais existe en tant que dossier dans le sous-répertoire du référentiel Geronimo dans le cadre de l'installation standard.
Enfin, j'ai trouvé 1 endroit qui a posé une solution de travail qui a réussi à résoudre mon problème. Vous devez masquer les fichiers jar du chargeur parent dans le plan de déploiement. Cela a été mis dans geronimo-web.xml avec mon fichier complet ci-dessous.
la source
Voici un exemple utilisant apache commons-fileupload:
la source
Le moyen le plus simple pourrait être trouvé pour les fichiers et les contrôles d'entrée, sans un milliard de bibliothèques:
la source
vous pouvez télécharger un fichier à l'aide de jsp / servlet.
côté serveur. utilisez le code suivant.
la source
De cet objet, vous devez obtenir des éléments de fichier et des champs, puis vous pouvez stocker dans le serveur comme suit:
la source
Envoyer plusieurs fichiers pour le fichier que nous devons utiliser
enctype="multipart/form-data"
et envoyer plusieurs fichiers
multiple="multiple"
dans la balise d'entréela source
PAGE HTML
FICHIER SERVLET
web.xml
Compilez le servlet UploadServlet ci-dessus et créez l'entrée requise dans le fichier web.xml comme suit.
la source