Dans le développement du système d'applications Web, les fonctions de téléchargement de fichiers et de téléchargement sont des fonctions très couramment utilisées. Aujourd'hui, parlons de l'implémentation des fonctions de téléchargement et de téléchargement de fichiers dans Javaweb.
Présentation de téléchargement de fichiers
1. La fonction du téléchargement de fichiers
Par exemple, le disque dur du réseau! Il est utilisé pour télécharger et télécharger des fichiers.
Pour remplir un CV complet sur le recrutement zhilien, vous devez également télécharger des photos.
2. Exigences pour le téléchargement de pages
Il existe de nombreuses exigences pour le téléchargement de fichiers, n'oubliez pas:
Le formulaire doit être utilisé, et non une méthode de formulaire hyperlien doit être publiée, pas un get
L'enctitype de la forme doit être multipart / format de forme
Ajoutez un champ de formulaire de fichier dans le formulaire, c'est-à-dire <entrée type = "file" name = "xxx" />
<form action = "$ {pageContext.request.contextPath} / fileuploadServlet" Method = "Post" EncType = "multipart / form-data"> nom d'utilisateur: <entrée type = "text" name = "username" /> <br/> File 1: name = "file2" /> <br/> <input type = "soumi" value = "soumi" /> </ form>3. Comparez la différence entre le formulaire de téléchargement de fichiers et le formulaire de texte normal
Affichez la différence entre "File Téléchargement Form" et "Formulaire de texte normal" via HttpWatch.
L'ENCTYPE du fichier Téléchargement Form = "Multipart / Form-Data", qui représente les données de formulaire en plusieurs parties;
Les formulaires de texte normaux peuvent être définis sans définir l'attribut ENCTYPE:
Lorsque Method = ”Post”, la valeur par défaut de ENCTYPE est Application / X-WWW-FORM-URLENCODEDED, ce qui signifie que lorsque Method = "Get" est utilisé, la valeur par défaut d'Enttype est nul et il n'y a pas de texte, il n'y a donc pas besoin de tester le formulaire de texte normal:
<form action = "$ {pagecontext.request.contextPath} / fileuploadServlet" metheth = "post"> username: <input type = "text" name = "username" /> <br/> file 1: <input type = "file" name = "file1" /> <br/> file 2: <input type = "file" name = "file2" /> <br/> <bouty type = "file" name = "file2" "/> <br/> <bouty type =" file "name =" file2 " Value = "Soumider" /> </ Form>Grâce à des tests HTTPWatch, en examinant le corps de données de la demande du formulaire, nous avons constaté qu'il n'y avait que le nom de fichier dans la demande, mais pas de contenu de fichier. C'est-à-dire que lorsque l'EnCType du formulaire n'est pas multipart / formulaire de forme, la demande ne contient pas le contenu du fichier, mais seulement le nom du fichier, ce qui signifie qu'il n'y a pas de différence entre l'entrée: fichier et entrée: texte dans un formulaire de texte normal.
Formulaire de téléchargement de fichiers de test:
<form action = "$ {pageContext.request.contextPath} / fileuploadServlet" Method = "Post" EncType = "multipart / form-data"> nom d'utilisateur: <entrée type = "text" name = "username" /> <br/> File 1: name = "file2" /> <br/> <input type = "soumi" value = "soumi" /> </ form>Grâce au test HTTPWatch, nous visuons la partie corporelle des données de demande du formulaire et avons constaté que la partie corporelle est composée de plusieurs composants, chaque composant correspond à un champ de formulaire et que chaque composant a ses propres informations d'en-tête. En dessous des informations d'en-tête se trouve une ligne vierge et en dessous de la ligne vide se trouve la partie du corps du champ. Plusieurs parties sont séparées par des séparateurs générés aléatoirement.
Les informations d'en-tête du champ de texte ne contiennent qu'une seule information d'en-tête, à savoir la disposition du contenu. La valeur de ces informations d'en-tête a deux parties. La première partie est fixe, à savoir les données de forme, et la deuxième partie est le nom du champ. Derrière la ligne vide se trouve la partie principale, et la partie principale est le contenu rempli dans la zone de texte.
Les informations d'en-tête du champ de fichier contient deux en-têtes, la disposition du contenu et le type de contenu. Il y a un nom de fichier supplémentaire dans la disposition du contenu, qui spécifie le nom de fichier téléchargé. Le type de contenu spécifie le type de fichier téléchargé. La partie principale du champ de fichiers est le contenu du fichier.
Veuillez noter que, car les fichiers que nous téléchargent sont tous des fichiers texte normaux, c'est-à-dire des fichiers TXT, ils peuvent être affichés normalement dans httpwatch. Si les fichiers téléchargés sont EXE, MP3, etc., alors ce que vous voyez sur httpwatch est brouillé.
4. Exigences pour les servlets lors du téléchargement de fichiers
Lorsque le formulaire soumis est un formulaire de téléchargement de fichiers, il existe également des exigences pour le servlet.
Tout d'abord, nous devons être sûrs que les données du formulaire de téléchargement de fichiers sont également encapsulées dans l'objet de demande.
La méthode request.getParameter (String) obtient le contenu de caractère de champ de formulaire spécifié, mais le formulaire de téléchargement de fichiers n'est plus le contenu de caractère, mais le contenu d'octet, il n'est donc pas valide.
À l'heure actuelle, vous pouvez utiliser la méthode de demande GetInputStream () pour obtenir l'objet ServleTinputStream. Il s'agit d'une sous-classe de InputStream. Cet objet ServleTinputStream correspond à la partie corporelle de la forme entière (à partir du premier diviseur à la fin), qui montre les données du flux d'analyse dont nous avons besoin. Bien sûr, l'analyse c'est une chose très gênante, et Apache nous a fourni des outils pour l'analyser: Commons-fileupload
Vous pouvez essayer d'imprimer le contenu de la demande.getInputStream () Stream et comparer les données de demande dans httpwatch.
public void doPost (request httpservletRequest, httpservletResponse réponse) lève servletException, ioException {inputStream in = request.getInputStream (); String s = ioutils.toString (in); System.out.println (s);}----------------------------- 7DDD3370AB2Content-Disposition: Form-Data; name = "nom d'utilisateur" Hello ----------------------------- 7DDD3370AB2Content-Disposition: Form-Data; name = "file1"; FileName = "A.TXT" Content-Type: Text / PLAINAAA ----------------------------- 7DDD3370AB2Content-Disposition: Form-Data; name = "file2"; FileName = "B.TXT" Type de contenu: texte / plainbbb ----------------------------- 7DDD3370AB2--
Commons-fileupload
Pourquoi utiliser Fileupload:
Il existe de nombreuses exigences pour le téléchargement de fichiers, n'oubliez pas:
Doit être un formulaire post;
L'enctitype de la forme doit être des données multipart / forme;
Ajoutez un champ de formulaire de fichier au formulaire, c'est-à-dire
Exigences du servlet:
Vous ne pouvez plus utiliser request.getParameter () pour obtenir des données de formulaire. Vous pouvez utiliser request.getInputStream () pour obtenir toutes les données de formulaire, au lieu des données d'un élément de formulaire. Cela signifie que vous n'utilisez pas Fileupload, nous devons analyser le contenu de request.getInputStream () nous-mêmes.
1. Présentation de Fileupload
FileUpload est un composant de téléchargement fourni par le composant Commons d'Apache. Son travail principal est de nous aider à analyser la demande.getInputStream ()
Les packages JAR requis par le composant Fileupload sont:
Commons-fileupload.jar, package de base
Commons-io.jar, package de dépendance
2. Application simple de Fileupload
Les classes de base de FileUpload sont: DiskFileItemFactory, ServletFileUpload, FileItem
Les étapes pour utiliser le composant Fileupload sont les suivantes:
// 1. Créez la classe d'usine DiskFileItemFactory Object DiskFileItemfactory Factory = new DiskFileItemFactory (); // 2. Créez un objet d'analyse à l'aide de l'usine ServletFileUpload Fileupload = new ServletFileUpload (Factory); // 3. Utilisez l'analyseur pour analyser la liste des objets de demande <FichierItem> list = fileupload.parsErequest (request);
DiskFileItemFactory Disk Fichier Item Factory Classe d'usine
public diskfileItemfactory (int sizethreshold, fichier référentiel)
Lors de la construction d'une usine, spécifiez la taille du tampon de mémoire et l'emplacement temporaire de stockage de fichiers.
SetSizethReshold public public (int sizethreshold)
Définir la taille du tampon de mémoire, par défaut 10k
public void setRepository (référentiel de fichiers)
Définissez l'emplacement de stockage de fichiers temporaires, par défaut System.getProperty ("java.io.tmpdir").
Tampon de mémoire: lors du téléchargement d'un fichier, le contenu du fichier téléchargé est d'abord enregistré dans le tampon de mémoire. Lorsque la taille du fichier téléchargé dépasse la taille du tampon, des fichiers temporaires seront générés du côté serveur.
Emplacement de stockage de fichiers temporaire: Téléchargez des fichiers dépassant la taille du tampon de mémoire pour générer des fichiers temporaires. Les fichiers temporaires peuvent être supprimés via la méthode delete () de FileItem
FileItem représente chaque partie des données du formulaire de téléchargement de fichiers
Nous présenterons la classe FileItem solennellement, qui est le résultat final que nous voulons. Un objet FileItem correspond à un élément de formulaire (champ de formulaire). Les champs de fichiers et les champs normaux existent sous une forme. Vous pouvez utiliser la méthode iSformField () de la classe FileItem pour déterminer si le champ de formulaire est un champ normal. S'il ne s'agit pas d'un champ normal, c'est un champ de fichiers.
Remarque: Étant donné que le formulaire de téléchargement de fichiers est codé à l'aide de données multipartiques / formulaires, différente de l'encodage d'URL traditionnel, toutes les méthodes getParameter () ne peuvent pas utiliser SetCacteRencoding () ne peuvent pas résoudre le problème brouillé des éléments d'entrée.
ServletFileUpload Fichier Téléchargez la classe de base
3. Exemple de téléchargement simple
Écrivez un exemple de téléchargement simple:
Le formulaire contient un champ de nom d'utilisateur et un champ de fichiers;
Servlet enregistre les fichiers téléchargés dans le répertoire des téléchargements, affichant le nom d'utilisateur, le nom de fichier, la taille du fichier, le type de fichier.
premier pas:
Pour compléter index.jsp, un seul formulaire est nécessaire. Notez que le formulaire doit être posté et que l'EnCype doit être MulitPart / Form Data
<form action = "$ {pagecontext.request.contextPath} / fileuploadServlet" Method = "Post" EncType = "multipart / form-data"> Nom d'utilisateur: <entrée type = "text" name = "username" /> <br/> Fichier 1: <put type = "file" name = "file" /> <br/> <put type = "souminer =" name = "File1" /> <br/> <put type = "soumentil =" soumest "Étape 2: Terminez FileuploadServlet
public void doPost (requête HttpServletRequest, réponse httpservletResponse) lance ServletException, ioException {// Parce que vous souhaitez imprimer avec la réponse, définissez son codage réponse.setContentType ("text / html; charset = utf-8"); // Créer des diskfileItemfactory d'usine DFIF = new DiskFileItemFactory (); // Créer un objet Parser à l'aide de Factory ServletFileUpload Fileupload = new ServletFileUpload (DFIF); Essayez {// Utilisez l'objet Parser pour analyser la demande et obtenez la liste FileItem List <Fichiers> list = fileupload.parsErequest (request); // Traverse tous les éléments du formulaire pour (fichier FileItem: list) {// Si l'élément de formulaire actuel est un élément de formulaire normal if (fileItem.isformField ()) {// Obtenez le nom de champ de la chaîne de formulaire de formulaire actuelle fieldName = fileitem.getFieldName (); // Si le nom de champ de l'élément de formulaire actuel est le nom d'utilisateur if (fieldname.equals ("nom d'utilisateur")) {// imprime le contenu de l'élément de formulaire actuel, c'est-à-dire le contenu entré par l'élément de formulaire de nom d'utilisateur Response.getWriter (). Print ("username:" + filetem.getString () + "<br/>"); }} else {// Si l'élément de formulaire actuel n'est pas un élément de formulaire normal, cela signifie que la chaîne de champ de fichiers name = fileItem.getName (); // obtient le nom du fichier téléchargé // Si le nom de fichier téléchargé est vide, aucun fichier téléchargé n'est spécifié if (name == null || name.isempty ()) {continué; } // Obtenez le chemin réel, correspondant à $ {Directory de projet} / téléchargement. Bien sûr, ce répertoire doit avoir String SavePath = this.getServletContext (). GetRealPath ("/ uploads"); // Créer un objet de fichier via le répertoire de téléchargements et le fichier fichier fichier fichier = new File (SavePath, name); // Enregistrez le fichier de téléchargement dans la localisation spécifiée fileItem.write (fichier); // imprime le nom du fichier de téléchargement Response.getWriter (). Print ("Télécharger le nom du fichier:" + name + "<br/>"); // imprime la taille du fichier de téléchargement Response.getWriter (). Print ("Télécharger la taille du fichier:" + fileItem.getSize () + "<br/>"); // imprime le type de fichier téléchargé Response.getWriter (). Print ("Télécharger le type de fichier:" + fileItem.getContentType () + "<br/>"); }}} catch (exception e) {throw new Servlexception (e); }}Détails de téléchargement de fichiers
1. Mettez le fichier téléchargé dans le répertoire Web-Inf
Si les fichiers téléchargés par l'utilisateur ne sont pas stockés dans le répertoire Web-INF, l'utilisateur peut accéder directement aux fichiers téléchargés via le navigateur, ce qui est très dangereux.
Si l'utilisateur télécharge un fichier A.JSP et que l'utilisateur accède au fichier A.JSP via le navigateur, le contenu de A.JSP sera exécuté. S'il y a l'instruction suivante dans a.jsp: runtime.getRuntime (). Exec ("Shutdown ST 1"); Alors tu le feras ...
Habituellement, nous créerons un répertoire de téléchargements dans le répertoire Web-inf pour stocker les fichiers téléchargés. Pour trouver ce répertoire dans le servlet, nous devons utiliser la méthode GetRealPath (String) de ServletContext. Par exemple, il y a l'instruction suivante dans mon projet Upload1:
ServletContext servletContext = this.getServletContext (); String SavePath = servletContext.getRealPath ("/ web-inf / uploads");Le sauvegarde est: f: / tomcat6_1 / webapps / upload1 / web-inf / uploads.
2. Nom de fichier (chemin complet, nom de fichier)
Le nom de fichier téléchargé peut être le chemin complet:
Le nom de fichier de téléchargement obtenu par IE6 est le chemin complet, tandis que le nom de fichier de téléchargement obtenu par d'autres navigateurs n'est que le nom du fichier. Nous devons encore faire face au problème des différences de navigateur
String name = file1FileItem.getName (); réponse.getWriter (). Print (name);
En utilisant différents navigateurs pour tester, IE6 renvoie le chemin complet pour télécharger le fichier. Je ne sais pas ce que fait IE6, ce qui nous cause beaucoup de problèmes, qui est de faire face à ce problème.
Il est également très simple de faire face à ce problème. Que ce soit un chemin complet ou non, nous interceptions simplement le contenu après le dernier "/"
String name = file1FileItem.getName (); int lastIndex = name.lastIndexof ("//"); // Obtenez la position du dernier "/" if (LastIndex! = -1) {// Notez que si ce n'est pas le chemin complet, alors il y aura non "/". name = name.substring (LastIndex + 1); // Obtenez le nom de fichier} réponse.getWriter (). print (name);3. Problème brouillé chinois
Le nom de fichier téléchargé contient chinois:
Lorsque le nom téléchargé contient chinois, vous devez définir le codage. Le composant Commons-FileUpload nous fournit deux façons de définir le codage:
request.SetcharAtterencoding (String): Cette méthode est la façon la plus familière que nous soyons.
fileupload.sethEaderendOing (String): cette méthode a une priorité plus élevée que la précédente
Le contenu du fichier du fichier téléchargé contient chinois:
Habituellement, nous n'avons pas besoin de nous soucier du contenu du téléchargement de fichiers, car nous allons enregistrer les fichiers téléchargés sur le disque dur! En d'autres termes, à quoi ressemble le fichier et à quoi il ressemble sur le serveur!
Mais si vous avez une telle exigence et que vous devez afficher le contenu du fichier téléchargé sur la console, vous pouvez utiliser FileItem.getString ("UTF-8") pour gérer l'encodage
Contenu du fichier texte et contenu de l'élément de formulaire normal Utilisez getString ("UTF-8") de la classe FileItem pour gérer l'encodage.
4. Le problème du fichier de téléchargement avec le même nom (renommée de fichiers)
Habituellement, nous enregistrons le fichier téléchargé par l'utilisateur dans le répertoire des téléchargements, mais que se passe-t-il si l'utilisateur télécharge un fichier avec le même nom? Cela entraînera une couverture. La méthode pour résoudre ce problème consiste à utiliser l'UUID pour générer un nom unique, puis à utiliser le "_" pour connecter le nom d'origine téléchargé par le fichier.
Par exemple, le fichier téléchargé par l'utilisateur est "ma photo d'un pouce.jpg". Après le traitement, le nom du fichier est: "891B3881395F4175B969256A3F7B6E10_MY ONE PHOTO.JPG". Cette méthode ne fera pas perdre le fichier son extension. En raison de l'unicité de l'UUID, le fichier téléchargé a le même nom, mais il n'y aura aucun problème avec le même nom côté serveur.
public void doPost (requête HttpServletRequest, réponse httpservletResponse) lève ServletException, ioException {request.SetcharAtterencoding ("utf-8"); DiskfileItemfactory dfif = new DiskFileItemFactory (); ServletFileUpload FileUpload = new ServletFileUpload (DFIF); try {list <FeleItem> list = fileupload.parsErequest (request); // Obtenez l'élément de deuxième formulaire, car le premier élément de formulaire est le nom d'utilisateur, le second est l'élément de formulaire de fichier fileItem fileItem = list.get (1); String name = fileItem.getName (); // Obtenez le nom de fichier // Si le client utilise IE6, alors vous devez obtenir le nom du fichier à partir du chemin complet int LasIndex = name.LastIndexof ("//"); if (LastIndex! = -1) {name = name.substring (LastIndex + 1); } // Obtenez le fichier téléchargé SavePath = this.getServletContext (). GetRealPath ("/ web-inf / uploads"); String uUid = Commonutils.UUID (); // Générer UUID String FileName = UUID + "_" + name; // Le nouveau nom de fichier est UUID + sous-ore + nom d'origine // Créer un objet de fichier, et le fichier Uploaded sera enregistré sur le chemin d'accès spécifié par ce fichier de fichier File File-Fichier, c'est-à-dire le fichier Upaded Directory // Filename, File Fitive File (Name File-Fichier (FilePAT Uilded, fichier de fichiers // fichier filen, fichier de fichier File File = newpat. nom de fichier); // Enregistrer le fichier item.write (fichier); } catch (exception e) {lancer un nouveau servletException (e); }}5. Un répertoire ne peut pas stocker trop de fichiers (Store Directory pour rompre)
Il ne devrait pas y avoir trop de fichiers stockés dans un répertoire. Généralement, 1 000 fichiers sont stockés dans un répertoire, et s'il y en a beaucoup, ce sera très "Cracky" lors de l'ouverture du répertoire. Vous pouvez essayer d'imprimer le répertoire C: / Windows / System32, vous le sentirez
Autrement dit, nous devons mettre les fichiers téléchargés dans différents répertoires. Cependant, un répertoire ne peut pas être utilisé pour chaque fichier téléchargé, car cette méthode conduira à trop de répertoires. Nous devons donc utiliser un algorithme pour "rompre"!
Il existe de nombreuses façons de le casser, comme utiliser des dates pour le casser, générer un répertoire tous les jours. Vous pouvez également utiliser la première lettre du nom du fichier pour générer un répertoire, et les fichiers avec la même lettre initiale sont placés dans le même répertoire.
Algorithme de rupture de date: s'il y a trop de fichiers téléchargés un certain jour, il y aura également trop de fichiers de répertoire;
L'algorithme pour briser la première lettre: si le nom du fichier est en chinois, car il y a trop de chinois, cela mènera à trop de répertoires.
Nous utilisons ici l'algorithme de hachage pour le casser:
Obtenez le HashCode du nom du fichier: int hcode = name.hashcode ()
Obtenez les 4 bits inférieurs de HCODE, puis convertissez-le en caractères hexadécimaux pour obtenir les 5 ~ 8 bits de HCODE, puis convertissez-le en caractères hexadécimaux pour générer une chaîne de répertoire en utilisant ces deux caractères hexadécimaux. Par exemple, les caractères 4 bits inférieurs sont "5"
L'avantage de cet algorithme est qu'un maximum de 16 répertoires sont générés dans le répertoire des téléchargements, et un maximum de 16 répertoires sont générés dans chaque répertoire, c'est-à-dire 256 répertoires, et tous les fichiers téléchargés sont placés dans ces 256 répertoires. Si le nombre maximum de chaque répertoire est de 1000 fichiers, un total de 256 000 fichiers peut être enregistré.
Par exemple, le nom du fichier de téléchargement est: nouveau document texte.txt, puis obtenez le code de hachage de "nouveau texte texte.txt", puis obtenez les 4 chiffres inférieurs du code de hachage et 5 à 8 chiffres. Si les 4 bits inférieurs sont: 9 et 5 ~ 8 bits sont 1, alors le chemin de sauvegarde du fichier est des téléchargements / 9/1 /
int hcode = name.hashcode (); // Obtenez le hashcode du nom de fichier // obtenez les 4 bits bas de Hcode et convertissez-le en chaîne de chaîne hexadécimale DIR1 = Integer.tohexString (Hcode & 0xf); // STORS STRAINE 5 ~ 8 bits de Hcode. >>> 4 & 0xf); // Connectez le chemin de sauvegarde du fichier au chemin complet sauvegarde = sauvegarde + "/" + dir1 + "/" + dir2; // Parce que ce chemin peut ne pas exister, créez-le comme un objet de fichier, puis créez une chaîne de répertoire pour s'assurer que le répertoire existe déjà nouveau avant d'enregistrer le fichier (SavePath) .MKDirs ();
6. Limites de taille pour les fichiers téléchargés individuels
Il est très simple de limiter la taille des fichiers téléchargés, juste setFileSizEMax (long) de la classe ServletFileUpload. Le paramètre est le nombre de limites supérieures d'octets du fichier téléchargé. Par exemple, ServletFileUpload.SetFileSizEMAX (1024 * 10) signifie que la limite supérieure est de 10 Ko.
Une fois que le fichier téléchargé dépasse la limite supérieure, une exception FileUploadBase.FileSizeliteXededEDException sera lancée. Nous pouvons obtenir cette exception dans le servlet et la sortie "Le fichier téléchargé dépasse la limite" à la page.
public void doPost (requête HttpServletRequest, réponse httpservletResponse) lève ServletException, ioException {request.SetcharAtterencoding ("utf-8"); DiskfileItemfactory dfif = new DiskFileItemFactory (); ServletFileUpload FileUpload = new ServletFileUpload (DFIF); // Définissez la limite supérieure du fichier unique téléchargé sur 10KB fileupload.setFileSizEMAX (1024 * 10); try {list <FeleItem> list = fileupload.parsErequest (request); // Obtenez l'élément de deuxième formulaire, car le premier élément de formulaire est le nom d'utilisateur, le second est l'élément de formulaire de fichier fileItem = list.get (1); String name = fileItem.getName (); // Obtenez le nom de fichier // Si le client utilise IE6, alors vous devez obtenir le nom du fichier à partir du chemin complet int LasIndex = name.LastIndexof ("//"); if (LastIndex! = -1) {name = name.substring (LastIndex + 1); } // Obtenez le fichier téléchargé SavePath = this.getServletContext (). GetRealPath ("/ web-inf / uploads"); String uUid = Commonutils.UUID (); // Générer UUID String FileName = UUID + "_" + name; // Le nouveau nom de fichier est UUID + sous-ore + nom d'origine int hcode = name.hashcode (); // convertir le hashcode du nom de fichier // STRING DROI Integer.tohexString (hcode & 0xf); // Obtenez les 5 ~ 8 bits de HCODE et convertissez-le en chaîne de chaîne hexadécimale dir2 = Integer.tohexString (hcode >>> 4 & 0xf); // Connectez le chemin de sauvegarde du fichier dans un chemin complet SavePath = SavePath + "/" + dir1 + "/" + dir2; // Parce que ce chemin peut ne pas exister, créez un objet de fichier, puis créez une chaîne de répertoire pour s'assurer que le répertoire existe déjà avant d'enregistrer le fichier nouveau fichier (sauvegarde) .mkDirs (); // Créer un objet de fichier, et le fichier téléchargé sera enregistré sur le chemin spécifié par ce fichier // SavePath, c'est-à-dire le répertoire de fichier téléchargé // nom de fichier, nom de fichier, nom de fichier; // Enregistrer FileItem.Write (fichier); } catch (exception e) {// Déterminez si le type de l'exception lancée est fileuploadbase.fileSizeliteXechedException // Si c'est le cas, cela signifie que la limite a été dépassée lors du téléchargement du fichier. if (e instanceof fileuploadbase.fileSizeliteXechedException) {// Enregistrez le message d'erreur dans la demande de demande.setAttribute ("msg", "le téléchargement a échoué! Le fichier téléchargé a dépassé 10kb!"); // transmettez la page index.jsp! Dans la page index.jsp, vous devez utiliser $ {msg} pour afficher le message d'erreur request.getRequestDispatcher ("/ index.jsp"). Forward (demande, réponse); retour; } Jetez un nouveau servletException (E); }}7. Limite de taille totale pour le téléchargement de fichiers
Le formulaire pour télécharger un fichier peut permettre à plusieurs fichiers d'être téléchargés, par exemple:
Parfois, nous devons limiter la taille d'une demande. C'est-à-dire le nombre maximum d'octets pour cette demande (somme de tous les éléments de formulaire)! L'implémentation de cette fonction est également très simple. Il vous suffit d'appeler la méthode SetSizEMax (longue) de la classe ServletFileUpload.
Par exemple, fileupload.setsizemax (1024 * 10);, la limite supérieure de la demande entière est de 10 Ko. Lorsque la taille de la demande dépasse 10 Ko, la méthode PARSEREQUEST () de la classe ServletFileUpload lancera une exception FileUploadBase.SizeliteXededEdException.
8. Taille du cache et répertoire temporaire
Pensez-y, si je télécharge un film Blu-ray, enregistrez d'abord le film dans la mémoire, puis le copiez sur le disque dur du serveur via la mémoire, alors votre mémoire peut-elle être mangée?
Par conséquent, le composant FileUpload ne peut pas enregistrer tous les fichiers en mémoire. FileUpload déterminera si la taille du fichier dépasse 10 Ko. Si c'est le cas, enregistrez le fichier sur le disque dur. S'il ne le dépasse pas, enregistrez-le en mémoire.
10KB est la valeur par défaut de Fileupload, nous pouvons le définir.
Lorsque le fichier est enregistré sur le disque dur, FileUpload enregistre le fichier dans le répertoire temporaire du système. Bien sûr, vous pouvez également définir le répertoire temporaire
public void doPost (requête HttpServletRequest, réponse httpservletResponse) lève ServletException, ioException {request.SetcharAtterencoding ("utf-8"); DiskfileItemfactory dfif = new DiskFileItemFactory (1024 * 20, nouveau fichier ("f: // temp")); ServletFileUpload FileUpload = new ServletFileUpload (DFIF); try {list <FeleItem> list = fileupload.parsErequest (request); FileItem FileItem = list.get (1); String name = fileItem.getName (); String SavePath = this.getServletContext (). GetRealPath ("/ web-inf / uploads"); // Enregistrer fileItem.write (path (path (sauvepath, name));} catch (exception e) {throw new Servlexception (e);}} File Path (String SavePath, String FileName) {// Obtenez le nom de fichier int à partir de la parole complète LastIndex = FileName.LastIndexof ("//"); FileName.SubString (LastIndex + 1); + Dir2; // Créer un nouveau fichier (SavePath) .mkDirs ();Téléchargement de fichiers
1. Télécharger 1 via servlet
Les ressources téléchargées doivent être placées dans le répertoire Web-Inf (il est OK tant que l'utilisateur ne peut pas accéder directement via le navigateur), puis le téléchargez via le servlet.
Donnez le lien hypertexte dans la page JSP, lien vers le téléchargement de téléchargement et fournissez le nom de fichier à télécharger. Ensuite, DownloadServlet obtient le chemin réel du fichier et écrit le fichier dans le flux de réponse.getOutputStream ().
télécharger.jsp
<body> Ceci est ma page JSP. <br> <a href = "<c: url value = '/ downloadservlet? path = a.avi' //>"> a.avi </a> <br/> <a href = "<c: url value = '/ downloadservlet? path = a.jpg' ///>"> a.jpg </a> <br/> <a href = "<c: url value = '/ downloadServlet? path = a.txt' ////> "> a.txt </a> <br/> </odyfing>
Downloadservlet.java
public void doGet (demande httpservletRequest, réponse httpservletResponse) lève ServletException, ioException {String filename = request.getParAmètre ("path"); String filepath = this.getServletContext (). GetRealPath ("/ web-inf / uploads /" + filename); Fichier fichier = nouveau fichier (filepath); if (! file.exists ()) {réponse.getWriter (). print ("Le fichier que vous souhaitez télécharger n'existe pas!"); retour; } Ioutils.copy (new FileInputStream (fichier), réponse.getOutputStream ());}Le code ci-dessus a les problèmes suivants:
1. Vous pouvez télécharger A.AVI, mais le nom de fichier dans la zone de téléchargement est Téléchargement de Téléchargement;
2. Vous ne pouvez pas télécharger a.jpg et a.txt, mais les afficher dans la page.
2. Télécharger 2 via servlet
Passons au problème dans l'exemple précédent, afin que le nom de fichier correct puisse être affiché dans la zone de téléchargement, et les fichiers A.JPG et A.TXT peuvent être téléchargés
Gérez le problème ci-dessus en ajoutant l'en-tête de contenu. Lorsque l'en-tête de contenu est défini, le navigateur apparaîtra dans la zone de téléchargement
Et vous pouvez également spécifier le nom du fichier téléchargé via l'en-tête de contenu!
String filename = request.getParameter ("path"); String filepath = this.getServletContext (). GetRealPath ("/ web-inf / uploads /" + filename); Fichier fichier = nouveau fichier (filepath); if (! file.exists ()) {réponse.getWriter (). print ("Le fichier que vous souhaitez télécharger n'existe pas!"); retour; } Response.Addheader ("Content-Disposition", "attachement; filename =" + filename); Ioutils.copy (new FileInputStream (fichier), réponse.getOutputStream ());Bien que le code ci-dessus puisse déjà gérer le téléchargement de fichiers tels que TXT et JPG, et également gérer le problème de l'affichage des noms de fichiers dans la zone de téléchargement, si le nom de fichier téléchargé est en chinois, il ne peut toujours pas
3. Télécharger 3 via servlet
Vous trouverez ci-dessous le problème de la gestion de l'affichage des Chinois dans la boîte de téléchargement!
En fait, cette question est très simple. Vous n'avez qu'à coder le chinois à travers l'URL!
télécharger.jsp
<a href = "<c: url value = '/ downloadServlet? Path = ce tueur n'est pas trop froid.avi' //>"> Ce tueur n'est pas trop froid.avi </a> <br/> <a href = "<c: url value = '/ downloadServlet? Path = baibing.jpg' />"> baibing.jpg </a> <br/> <a href = "<c: url value = '/ downloadServlet? Path = Description.txt' />"> Description.txt </a> <br/>
Downloadservlet.java
String filename = request.getParamètre ("Path"); // Dans la demande de GET, le paramètre chinois contient le chinois et doit être converti par vous-même. // Bien sûr, si vous utilisez le "filtre d'encodage global", vous n'avez pas besoin de le faire ici FileName = new String (filename.getBytes ("isO-8859-1"), "utf-8"); String filepath = this.getservletContext (). GetRealPath ("/ web-inf / uplow File (filepath); if (! File.exists ()) {réponse.getWriter (). Print ("Le fichier que vous souhaitez télécharger n'existe pas!"); return;} // Tous les navigateurs utiliseront le codage local, c'est-à-dire que le système d'exploitation chinois a utilisé GBK // après que le navigateur aura reçu ce nom de fichier, il utilisera ISO-8859-1 pour décoder filename = new String (filename.getbytes ("GBK"), "ISO-8859-1"); réponse. FileName); ioutils.copy (new FileInputStream (fichier), réponse.getOutputStream ());Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.