1. Présentation de téléchargement de fichiers
Pour réaliser la fonction de téléchargement de fichiers dans le développement Web, deux étapes sont nécessaires:
1. Ajouter Télécharger les éléments d'entrée sur la page Web
<form action = "#" Method = "Post" ENCTYPE = "Multipart / Form-data"> <Input Type = "File" name = "FileName1" /> <br> <Input Type = "File" Name = "FileName2" /> <br> <Input Type = "Soumide" Value = "upload" /> <form> <! - 1. La méthode du formulaire est incontournable 2. Après avoir défini cette valeur, lorsque le navigateur télécharge le fichier, il attachera les données de fichier au corps du message de demande HTTP et utilise le protocole MIME pour décrire le fichier téléchargé pour faciliter le récepteur pour analyser et traiter les données téléchargées. 3. L'attribut de nom de l'entrée doit être défini, sinon le navigateur n'enverra pas les données de fichier téléchargées. ->
2. Lisez les données de téléchargement de fichiers dans Servlet et enregistrez-les sur le disque dur du serveur
L'objet de demande fournit une méthode GetInputStream, à travers laquelle les données soumises par le client peuvent être lues. Cependant, comme les utilisateurs peuvent télécharger plusieurs fichiers en même temps, il s'agit d'une tâche très gênante de programmer et de lire directement les données téléchargées du côté servlet et d'analyser séparément les données de fichier correspondantes.
Par exemple, ce qui suit est un contenu du protocole HTTP de la demande envoyée par le navigateur intercepté lors du téléchargement du fichier:
Accept-Language: ZH-HANS-CN, ZH-HANS; Q = 0,5Content-Type: Multipart / Form-Data; boundary=---------------------------7dfa01d1908a4UA-CPU: AMD64Accept-Encoding: gzip, deflateUser-Agent: Mozilla/5.0 (Windows NT 6.2; Win64; x64; Trident/7.0; rv:11.0) like GeckoContent-Length: 653Host: localhost:8080Connection: Keep-AlivePragma: No-CacheCookie: JSessionID = 11CEFF8E271AB62CE676B5A87B746B5F ----------------------------- 7DFA01D1908A4Content-Disposition: Form-Data; name = "nom d'utilisateur" Zhangsan ----------------------------- 7DFA01D1908A4Content-Disposition: Form-Data; name = "userpass" 1234 ----------------------------- 7DFA01D1908A4Content-Disposition: Form-Data; name = "filename1"; filename = "c: /users/asus/desktop/upload.txt" Content-Type: text / plainThis est le premier contenu de fichier! ----------------------------- 7DFA01D1908A4Content-Disposition: form-data; name = "filename1"; filename = "c: /users/asus/desktop/upload2.txt" Content-Type: text / plainThis est le deuxième contenu du fichier! Bonjour ----------------------------- 7DFA01D1908A4--
Il peut également être vu à partir des données ci-dessus qu'il est difficile d'écrire un programme robuste et stable si vous divisez et lisez manuellement les données. Par conséquent, pour faciliter les utilisateurs pour traiter les données de téléchargement, l'organisation Open Source Apache fournit un composant open source (Commons-FileUpload) utilisé pour traiter les téléchargements de fichiers de formulaire. Ce composant a d'excellentes performances et son API est extrêmement simple à utiliser, ce qui permet aux développeurs d'implémenter facilement la fonction de téléchargement de fichiers Web. Par conséquent, dans le développement Web, la fonction de téléchargement de fichiers est généralement implémentée à l'aide du composant Commons-FileUpload.
Deux packages en pot doivent être importés: Commons-fileupload, Commons-io
Response.SetContentType ("Text / Html; charSet = UTF-8"); // Définir la réponse de la réponse. Printwriter writer = réponse.getWriter (); // Obtenir un flux de sortie de réponse servletInputStream inputStream = request.getInputStream (); // get request input stream / * * 1. Ce paramètre définit la taille du tampon de mémoire, la valeur par défaut est de 10k. Lorsque le fichier de téléchargement est supérieur à la taille du tampon, le composant FileUpload téléchargera le fichier à l'aide du référentiel de fichiers temporaire * @param java.io.file Repository, ce paramètre spécifie le répertoire de fichiers temporaire, la valeur par défaut est System.getProperty ("java.io.tmpdir"); * * Si un constructeur sans paramètres est utilisé, setSizethReshold (int sizethReshold), setRepository (java.io.file Repository) * La méthode est définie manuellement * / diskfileItemfactory factory = new DiskFileItemFactory (); int sizethReshold = 1024 * 1024; Factory.SetSizethreshold (sizethreshold); File Repository = nouveau fichier (request.getSession (). GetServletContext (). GetRealPath ("temp")); // system.out.println (request.getSession (). GetServletContext (). GetRealPath ("temp")); // system.out.println (request.getRealPath ("temp")); factory.setRepository (référentiel); / * * 2. Utilisez l'objet DiskFileItemFactory pour créer un objet ServletFileUpload et définissez la taille du fichier téléchargé * * L'objet ServletFileUpload est responsable du traitement des données de fichiers téléchargées et de chaque élément d'entrée dans le formulaire en fichieritem * Les méthodes courantes de cet objet sont: * BOOLEAN ISMULTATCONTCENT (demande); Déterminez si le formulaire téléchargé est Type multipart / Form Data * liste PARSEREQUEST (demande); analyser l'objet de demande, envelopper chaque élément d'entrée dans le formulaire dans un objet FileItem et renvoyer une collection de liste qui enregistre tous les fichiers FileItems * void setFileSizEMAX (Long FilesizEMax); Définissez la valeur maximale d'un seul fichier téléchargé * void setSizEMax (long sizemax); Définissez la valeur maximale de la quantité totale de wenjiang * void SetheDerencoding (); Définissez le format d'encodage pour résoudre le problème des noms de fichiers de téléchargement de code brouillé * / servletFileUpload upload = new ServletFileUpload (Factory); upload.setheDerencoding ("UTF-8"); // Définissez le format d'encodage pour résoudre le problème des noms de fichiers de téléchargement de code brouillé / * * 3. Appelez le servletFileUpload.PaSerequest Méthode pour analyser l'objet de demande et obtenir un objet de liste qui enregistre tous les contenus Uploaded * / list <FileItem> PARSEREQUEST = NULL; essayez {parserequest = upload.parseRequest (request); } catch (fileUpLoadexception e) {e.printStackTrace (); } / * * 4. Ilétèrent la liste. Chaque itération d'un objet FileItem, appelez sa méthode iSformField pour déterminer s'il s'agit d'un téléchargement de fichiers * True signifie qu'il s'agit d'un champ de formulaire normal, puis d'appeler les méthodes getFieldName et GetString pour obtenir le nom et la valeur du champ du champ * FAUX est le fichier de téléchargement, puis appelle la méthode GetInputStream pour obtenir le flux de données de données ou un objet de forme de fichier Uplow de cet objet est: * booléen isformfield (); Détermine si FileItem est un objet de téléchargement de fichiers ou un objet de formulaire normal * true signifie qu'il s'agit d'un champ de formulaire normal, * puis appelez getFieldName et getString méthodes pour obtenir le nom et la valeur du champ du champ * false comme le fichier de téléchargement, * puis appelez getName () pour obtenir le nom de fichier du fichier de téléchargement. Remarque: Certains navigateurs transportent des chemins clients et doivent se soustraire * appelez la méthode getInputStream () pour obtenir le flux d'entrée de données, afin de lire les données de téléchargement * delete (); signifie qu'après la fermeture du flux d'entrée FileItem, la suppression des fichiers temporaires est supprimée. * / for (fileItem fileItem: ParsErequest) {if (fileItem.isformField ()) {// représente le champ normal if ("username" .equals (fileItem.getFieldName ()))) {String username = fileItem.getString (); writer.write ("Votre nom d'utilisateur:" + nom d'utilisateur + "<br>"); } if ("userpass" .equals (fileItem.getFieldName ()))) {string userpass = fileItem.getString (); writer.write ("Votre mot de passe:" + userpass + "<br>"); }} else {// signifie un fichier téléchargé // Les fichiers téléchargés par différents navigateurs peuvent avoir un nom de chemin, et vous devez couper la chaîne clientName = fileItem.getName (); String filename = ""; if (clientName.Contains ("//")) {// Si "/" signifie un nom avec un chemin, le dernier nom de fichier est intercepté filename = clientName.substring (clientName.LastIndexof ("//")). substring (1); } else {filename = clientName; } UUId randomUuid = uuid.randomuuid (); // générer un identifiant de longue date de longue date de longue date de longue date = randomUuid.toString () + filename; / * * Concevoir un algorithme de génération de répertoire. Si le nombre total de fichiers téléchargés par l'utilisateur est des ordres de millions d'ordres de grandeur ou plus, les placer dans le même répertoire rend l'indice de fichier très lent. * Par conséquent, il est très nécessaire de concevoir une structure de répertoire pour stocker des fichiers de manière dispersée, et raisonnablement * convertir l'algorithme de hachage UUID en une chaîne octale plus petite, * à partir du premier morceau de cette chaîne, chaque personnage représente un répertoire de premier niveau, donc un directif huit est construit, avec un répertoire de premier niveau. Une structure de répertoire très efficace pour le serveur et le système d'exploitation * / int hashuuid = randomUuid.hashcode (); String hexuuid = Integer.tohexString (hashuuid); //System.out.println(hexuuid); // Obtenez le chemin absolu dans quel dossier pour stocker le fichier téléchargé dans String filepath = request.getSession (). GetServletContext (). GetRealPath ("upload"); pour (char c: hexuuid.tocharay ()) {filepath = filepath + "/" + c; } // Si le répertoire n'existe pas, générez un fichier de répertoire de huitième niveau filepathfile = nouveau fichier (filepath); if (! filepathfile.exists ()) {filepathfile.mkDirs (); } // Lisez le fichier du flux d'entrée de la demande et écrivez sur le serveur inputStream inputStream2 = fileItem.getInputStream (); // Créer un fichier sur le fichier côté serveur Fichier = nouveau fichier (filepath + "/" + nom de fichier); BufferedOutputStream bos = new BufferedOutputStream (new FileOutputStream (fichier)); octet [] tampon = nouveau octet [10 * 1024]; int len = 0; while ((len = inputStream2.read (tampon, 0, 10 * 1024))! = - 1) {bos.write (tampon, 0, len); } writer.write ("Vous avez téléchargé le fichier" + clientName + "avec succès <br>"); // ferme la ressource bos.close (); inputStream2.close (); }} // Notez que le fichier téléchargé d'Eclipse est enregistré dans le répertoire en cours d'exécution du projet, et non dans le répertoire du projet dans Workspace.2. Problèmes qui nécessitent une attention particulière au téléchargement de fichiers: (ces problèmes sont tous fournis avec des solutions simples dans le code ci-dessus)
1. Où stocker des fichiers
Pour garantir la sécurité du serveur, le fichier téléchargé doit être enregistré dans le répertoire Web de l'application ou un répertoire non géré par le serveur Web. Si l'utilisateur télécharge un fichier avec du code exécutable, tel qu'un fichier JSP, et y accède en fonction du chemin d'accès d'épissage, il peut tout faire du côté du serveur.
2. Afin d'empêcher plusieurs utilisateurs de télécharger des fichiers avec le même nom de fichier, ce qui entraîne l'écrasement des fichiers, le téléchargeur de fichiers doit s'assurer que le fichier téléchargé a un nom de fichier unique .
Renommer en utilisant UUID + User Téléchargez le nom de fichier
À propos de uuid:
UUID (identifiant universellement unique) L'identifiant unique mondial se réfère au nombre généré sur une machine, ce qui garantit qu'il est unique à toutes les machines en même temps et en même temps. Selon les normes établies par l'Open Software Foundation (OSF), l'adresse de la carte Ethernet, le temps nanoseconde, le code d'identification de la puce et de nombreux numéros possibles sont utilisés. Il se compose de la combinaison des parties suivantes: la date et l'heure actuelles (la première partie de l'UUID est liée au temps. Si vous générez un autre UUID quelques secondes après avoir généré un UUID, la première partie est différente, le reste est le même), la séquence d'horloge, la carte réseau unique n'est pas obtenue dans une autre voie), il est obtenu à partir de la carte réseau, et aucune carte de réseau n'est obtenue dans une autre voie), le seul Disadv UUID est que la chaîne de résultats générée sera relativement longue.
Il s'agit d'un long nombre de 128 bits, généralement exprimé en hexadécimal. L'idée principale de l'algorithme est de générer un GUID en combinaison avec la carte réseau de la machine, l'heure locale et un numéro instantané. Théoriquement, si une machine génère 100 000 guids par seconde, il peut être garanti (dans le sens de la probabilité) que 3240 ans ne seront pas répétés.
À partir de JDK1.5, la génération d'Uuids est devenue une chose simple, pensant que JDK a implémenté UUIDS:
java.util.uuid, appelez-le directement.
UUid uuid = uUid.randomuuid ();
String s = uuid.randomuuid (). ToString (); // L'ID de clé principale utilisé pour générer la base de données est très bon. .
L'UUID est composé d'un nombre de seize chiffres, qui s'exprime sous la forme de
550E8400-E29B-11D4-A716-446655440000
3. Afin d'éviter trop de fichiers dans un seul répertoire et d'affecter la vitesse de lecture et d'écriture des fichiers, le programme qui gère les fichiers de téléchargement doit choisir l'algorithme de génération de structure de répertoire approprié en fonction du volume total de téléchargement possible et stocker les fichiers téléchargés de manière dispersée. Par exemple, utilisez la méthode HashCode pour créer un répertoire à plusieurs niveaux.
4. Si différents utilisateurs téléchargent le même fichier, il n'est pas nécessaire de stocker de nombreuses copies du même fichier côté serveur. C'est un gaspillage de ressources. Un algorithme doit être conçu pour résoudre le problème des fichiers en double.
5. Le principe de la technologie JSP met automatiquement l'implémente multi-threading. Par conséquent, les développeurs n'ont pas besoin de considérer les opérations multiples de fichiers de téléchargement
3. Téléchargement de fichiers
<% ArrayList <string> filenames = new ArrayList <string> (); filenames.add ("file / aa.txt"); filenames.add ("file / bb.jpg"); pour (String File Name: FileNames) {%> <formulaire form = "downloadServlet" metheth = "get"> <input type = "Hidden" name = "filename" value = "<% = filename%>" /> <input type = "soumide" value = téléchargement: <% = filename%> "/> </ form> <%}%> request.secharactera String filename = request.getParameter ("FileName"); String urlName = urlencoder.encode (nom de fichier, "utf-8"); // empêcher la réponse brououillée chinoise.sethEader ("contenu-disposition", "attachement; filename =" + urlName); FileInputStream fis = new FileInputStream (nouveau fichier (request.getSession (). GetServletContext (). GetRealPath (filename))); BufferedInputStream bis = new BufferedInputStream (FIS); ServletOutputStream sos = réponse.getOutputStream (); octet [] tampon = nouveau octet [1024]; int len = 0; while ((len = bis.read (tampon, 0, 1024))! = - 1) {sos.write (tampon, 0, len); } bis.close (); fis.close ();4. Utilisez le composant SmartUpload dans SSH pour simplifier le téléchargement de fichiers et télécharger
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.