1. Aperçu du cours
Dans le développement du système d'applications Web, la fonction de téléchargement de fichiers est une fonction très courante. Aujourd'hui, parlons principalement de l'implémentation technique pertinente de la fonction de téléchargement de fichiers dans Javaweb. Avec le développement rapide de la technologie Internet, les exigences de l'expérience des utilisateurs pour les sites Web augmentent de plus en plus. Il existe également de nombreux points innovants dans la technologie de la fonction de téléchargement de fichiers, tels que le téléchargement asynchrone, le téléchargement de glisser-déposer, le téléchargement de pâte, de télécharger la surveillance des progrès, les vignettes de fichiers, la transmission continue de point d'arrêt de fichier grand fichier, la transmission instantanée de fichiers importante, etc.
Bases requises pour ce cours:
Comprendre le contenu de base du protocole HTTP
Technologie de fonctionnement de base du flux IO
Bases du servlet
Connaissance de base de la technologie JavaScript / jQuery
2. Bases du téléchargement de fichiers
Pour le téléchargement de fichiers, le navigateur soumet le fichier du côté serveur sous la forme d'un flux pendant le processus de téléchargement, et toutes les données de streaming seront transportées vers le côté serveur avec la demande HTTP. Par conséquent, le format du contenu demandé lors du téléchargement du fichier doit être essentiellement compris.
Page de téléchargement de fichiers:
<form action = "/ itheimaupload / uploadServlet" metheth = "post" EncType = "multipart / form-data"> Veuillez sélectionner le fichier téléchargé: <input type = "file" name = "attach" /> <br/> <input type = "soumed" value = "soumed" /> </ form>
Contenu de la demande HTTP:
3. L'arrière-plan Java utilise le servlet pour recevoir des fichiers
Il est gênant si vous utilisez Servlet pour obtenir le flux d'entrée des fichiers téléchargés, puis analysez les paramètres de demande. Par conséquent, d'une manière générale, l'arrière-plan choisit d'utiliser le composant de téléchargement de fichiers Common-FileUpload, l'outil open source d'Apache.
// Code d'arrière-plan Java: Commons-FileUpload Component uploads Fichier public class uploadServlet étend httpServlet {public void doGet (httpsservletRequest request, httpservletResponse réponse) lève Servlexception, ioException {// 1. Configurer le cache diskfileItemfactory factory = new DiskFileItemFactory (1 * 1024 * 1024, nouveau fichier ("c: / tempfiles /")); // 2. Créer un objet ServleFileUpload ServletFileUpload sfu = new ServletFileUpload (Factory); // résolvez le problème chinois du nom de fichier sfu.setheDerencoding ("utf-8"); // 3. Résoudre essayer {list <leitem> list = sfu.parsErequest (request); // résoudre tous les contenus if (list! = Null) {for (fileItem item: list) {// déterminer s'il s'agit d'un paramètre de formulaire normal if (item.isformField ()) {// ordinaire de paramètres de formulaire //) valeur = item.getString ("utf-8"); } else {// file if (item.getName ()! = null &&! item.getName (). equals ("")) {// Enregistrer sur le serveur FileUtils de disque dur ("c: / targetFiles /" + item.getName ())); itele. (FileUpLoAdException e) {e.printStackTrace ();}} public void doPost (HttpServLetRequest Request, HttpServletResponse Response) lève Servlexception, ioException {doget (request, réponse);}}4. Utilisez Webuploader pour télécharger des composants
À l'extrémité avant de la page de téléchargement de fichiers, nous pouvons choisir d'utiliser des composants de téléchargement plus utiles, tels que le composant open source de Baidu. Ce composant peut essentiellement répondre à certaines fonctions quotidiennes du téléchargement de fichiers, telles que le téléchargement asynchrone, le téléchargement de glisser-déposer, de coller le téléchargement, de télécharger la surveillance des progrès, les vignettes des fichiers et même les points de rupture de fichiers importants pour continuer la transmission et la transmission de fichiers importante en secondes.
Téléchargez le composant WebUpload
http://fex.baidu.com/webuploader/ Téléchargez le package Webupload sur le site officiel de Webupload
Structure du répertoire WebUpload:
Demo de téléchargement de fichiers de base (y compris les progrès de téléchargement)
l'extrémité avant
1.1 Importez le CSS requis, JS sur la page
<link rel = "Stylesheet" type = "text / css" href = "$ {pagecontex } /js/jquery-1.10.2.min.js "> </ script> <script type =" text / javascript "src =" $ {pagecontext.request.contextpath} /js/webuploder.js "> </ script>1.2 Écrivez la balise de la page de téléchargement
<! - Télécharger Div -> <div id = "uploader"> <! - Afficher les informations sur la liste des fichiers -> <ul id = "FileList"> </ul> <! - Sélectionnez la zone de fichier -> <div id = "filepicker"> Cliquez pour sélectionner le fichier </v> </div>
1.3 Écriture de code WebUpload
<Script Type = "Text / JavaScript"> // 1. Initialisez WebUpload et configurer les paramètres globaux var uploader = webuploader.create ({// flashk contrôle adresse swf: "$ {pageContext.request.contextPath} /js/uploader.swf", // backend Soumission Address Server: "$ {pageConText.request.contextPath} / uploadServert", // Sélectionner le fichier de piste: Contrôle de la commande: "#FilePicker", // Fichier de téléchargement automatique Auto: true,}); // 2. Après avoir sélectionné le fichier, l'affichage de la file d'attente des informations de fichier // enregistre l'événement FileEued: déclenché lorsque le fichier est ajouté au fichier // file: représente le fichier uploder.on actuellement sélectionné ("fileeUed", function (file) {// Ajouter des informations de fichier div $ ("# fileList"). class = 'fileInfo'> <span> "+ file.name +" </span> <div class = 'state'> en attente de upload ... </ div> <span class = 'text'> </span> </div> ");}); // 3. Enregistrez Télécharger Progress Ecoute // Fichier: Fichier de téléchargement // pourcentage: la proportion des progrès actuels. Le maximum est 1. Par exemple: 0.2uploadher.on ("uploadProgress", fonction (fichier, pourcentage) {var id = $ ("#" + file.id); // mise à jour des informations d'état id.find ("div.state"). Texte ("upload ..."); // Update pourcentage de téléchargement pour le pourcentage de téléchargement id.find ("span.text"). text (math.round (pourcentage * 100) + "%");}); // 4. Inscrivez-vous et téléchargez un fichier d'écoute //: Fichier téléchargé // Réponse: données renvoyées par l'arrière-plan, return uploader.on ("uploadsuccess", fonction (fichier, réponse) {// mise à jour des informations d'état $ ("#" + file.id) .find ("div.state"). Text ("uploaded");});2) Code du servlet backend
DiskfileItemfactory factory = new DiskFileItemFactory (); servletFileUpload sfu = new ServletFileUpload (factory); sfu.setheDerencoding ("utf-8"); try {list <fileItem> iteless = sfu.parserequest (request); for (filetem item: item Informations} else {// Informations de fichier // juger que seuls les fichiers doivent être enregistrés et traités System.out.println ("Nom de fichier reçu:" + item.getName ()); // Copiez le fichier sur le disque dur dans le fichier d'arrière-plan.CopyInputStreamTofile (item.getInputStream (); Économise avec succès ");}}} catch (fileUpLaDexception e) {e.printStackTrace ();}Générer des miniatures d'image
Point clé: appelez uploader.makethumb () Méthode pour générer des miniatures
uploadher.on ("filequeUed", function (file) {// APPEND Fichier Informations div $ ("# fileList"). APPEND ("<div id = '" + file.id + "' class = 'fileInfo'> <img /> <span>" + file.name + "</ span> <div class = 'state'> en attente de téléchargement ... </v> <pandi class = 'text'> </span> </ div> "); // Faire des vignettes de l'image: appelez makethumb () méthode // erreur: Échec de la création de miniatures // src: chemin des miniatures uploader.makethumb (file, fonction (erreur, src) {var id = $ (" # "+ file.id); // si il échoue," ne peut pas prévoir "est affiché". if (error) {id.find ("img"). Remplacewith ("ne peut pas prévisualiser");} // s'il réussit, la vignette sera affichée à la position spécifiée id.find ("img"). att ("src", src);Faire glisser, coller et télécharger
1) Ajoutez une div à la zone de traînée sur la page
<! - Téléchargez Div -> <div id = "uploader"> <! - Fichier glisser la zone -> <div id = "dndarea"> <p> Faire glisser le fichier directement ici pour télécharger automatiquement </p> </iv> <! - Sélectionner des informations sur la liste des fichiers -> <ul id = "FileList"> </ul> <! - Sélectionnez File Area -> <div id = "filempick
2) Ajouter des paramètres de glisser-déposer aux paramètres de configuration globale du webuploader
// 1. Initialiser Webupload et configurer les paramètres globaux var uploader = webuploader.create ({// flashk de contrôle de contrôle swf: "$ {pagecontex Pick: "# filepicker", // file de téléchargement automatique Auto: true, // activer la fonction de glisser-déposer, spécifiez la zone de glisser dnd: "# dndarea", // désactiver la fonction de glisser-déposer dans d'autres endroits de la page pour empêcher la page d'ouvrir directement le fichier Disableglobaldnd: true // activer la passe: "# uploder"});Télécharger des fichiers volumineux en morceaux
1) Ajouter des paramètres de téléchargement de blocs aux paramètres globaux du webuploader
// 1. Initialiser Webupload et configurer les paramètres globaux var uploader = webuploader.create ({// flashk de contrôle de contrôle swf: "$ {pagecontex Choisissez: "# filepicker", // file de téléchargement automatique Auto: true, // Activer la fonction de glisser-déposer, spécifiez la fonction de glisser DND: "# dndarea", // Désactiver la fonction de glisser-déposer dans d'autres endroits pour prévenir la page d'ouvrir le fichier désactiver directement Globaldnd: VRAI, // Activer la fonction de pâte, la fonction de pâte: "# uploder", // Set in Chunked: true, who Chunked: true, // Taille de fichier par bloc (par défaut 5m) ChunkSize: 5 * 1024 * 1024, // Ouvrez plusieurs threads simultanés (par défaut 3) Threads: 3, // Lors du téléchargement du fichier actuel, prepareNextFile: true});2) Surveiller trois points dans le temps pour le téléchargement de fichiers
Après avoir ajouté les trois configurations ci-dessus, vous constaterez que lorsque le fichier dépasse 5 m, le webuploader enverra automatiquement le fichier à l'arrière-plan.
Chaque demande de bloc contient des informations:
Vous pouvez écouter trois points temporels importants dans les téléchargements de fichiers en morceaux.
Avant-SEND-FILE: APPELER AVANT ENFEND AVANT-END: S'il y a des blocs, appelez après-SEND-FILE avant que chaque bloc soit envoyé: appelé après que tous les blocs soient envoyés // 5. Surveillez les trois points de téléchargement du fichier (Remarque: Cette section de code doit être placée avant Webuploader.Create) // Point de temps 1 :: avant que tous les blocs ne soient téléchargés (1. La marque unique du fichier peut être calculée; 2. Transmission continue) // Étape 3: Une fois que tous les morceaux sont téléchargés avec succès (1. Informez l'arrière-plan des fichiers de morceaux pour fusionner) webuploader.uploader.register ({"Before-Sennd-File": "BeforendFile" Les morceaux BeforeSendFi le: fonction () {// 1. Demandez si l'arrière-plan a enregistré le bloc actuel. S'il existe, sautez le fichier de blocs pour réaliser la fonction de transmission continue de point d'arrêt}, // Étape 3: Appelez cette fonction une fois que tous les blocs sont téléchargés avec succès après-SendFile: function () {// 1. S'il est téléchargé en blocs, tous les fichiers de blocs sont fusionnés via l'arrière-plan}});Logique avant-file:
// Utilisez la méthode MD5File () pour calculer la balise unique du fichier // Cette fonction reçoit un DeferredBeForeSendFile: fonction (fichier) {// Créer un DeferredVar Deferred = webuploader.deferred (); // 1. Calculez la balise unique du fichier, utilisée pour la transmission continue de point d'arrêt et la deuxième transmission (new WebuPloader.uploader ()). MD5File (fichier, 0,5 * 1024 * 1024) .Progress (fonction (pourcentage) {$ ("#" + file.id) .find ("div.state"). Récupéré ... ");}). puis (fonction (val) {uniqueFileTag = Val; $ (" # "+ file.id) .find (" div.state "). Texte (" Informations sur le fichier obtenues avec succès "); // uniquement lorsque les informations du fichier sont obtenues avec succès, la prochaine opération sera effectuée Deferred.Resolve ();}); // Alert (unique Demandez si l'arrière-plan a enregistré le fichier. S'il existe, le fichier sera ignoré pour réaliser la deuxième fonction de passe // return Deferred.Promis ();}Avant sa logique:
// Envoyez une balise unique du fichier actuel à l'arrière-plan, qui est utilisé pour créer un répertoire qui enregistre le fichier de morceaux Beforesend: function () {// transporte la balise unique du fichier actuel sur l'arrière-plan, qui est utilisé pour créer un répertoire qui enregistre le fichier Chunked ce.owner.options.formdata.filemd5 = filemd5;}3) L'arrière-plan doit enregistrer tous les fichiers en morceaux
// Créez un répertoire pour chaque fichier et enregistrez tous les fichiers de morceaux de ce fichier // juger s'il a été téléchargé dans des morceaux if (Chunks! = Null) {System.out.println ("Chunk Traitement ..."); // Créer un répertoire temporaire pour enregistrer tous les fichiers Chunked Chunksdir = nouveau fichier (ServerPath + "/" + filemd5); if (! chunksdir.exists ()) {chunksdir.mkdir ();} if (chunk! = null) {// Enregistrer chunkfile chunkfile = nouveau fichier (chunksdir.getpath () + "/" + chunk); fileutils.copyInputStremtoFile (item.getUputStream (), chunkfile);}4) La réception informe le backend pour fusionner tous les fichiers
// La réception avertit l'arrière-plan pour fusionner les fichiers Logique du fichier After-Send: AftersendFile: fonction (fichier) {// 1. En cas de téléchargement dans des morceaux, fusionnez tous les fichiers de morceaux via l'arrière-plan // demande l'arrière-plan pour fusionner les fichiers $ .ajax ({type: "post", url: "$ {pageContex nom de fichier: file.name}, dataType: "json", succès: function (réponse) {alert (réponse.msg);}});} // fusion en arrière-plan tous les fichiers de morceaux if ("MergeChunks" .Equals (action)) {system.out.println ("start Merge Files ..."); // merge file String FileMd5 = request.getParater ("FideMd"); fileName = request.getParameter ("FileName"); // lire tous les fichiers dans le fichier du répertoire f = nouveau fichier (serverPath + "/" + filemd5); file [] filearray = f.listfiles (new FileFilter () {// exclude répertoire true;}}); // converti en une collection pour faciliter la liste de tri <Fichier> FileList = new ArrayList <Fichier> (arrays.aslist (filearray)); // trier de petite à grande collection.sort (fileList, nouveau comparateur <fichier> () {public int compare (fichier o1, file o2) Integer.ParseInt (o2.getName ())) {return -1;} return 1;}}); fichier outputFile = new File (serverPath + "/" + fileName); // Créer le fichier OutputFile.CreateWFile (); // output Stream FileChannel OutChannel = New InchannElnel; pour (fichier de fichier: fileList) {inchannel = new FileInputStream (fichier) .getChannel (); inchannel.transferto (0, inchannel.size (), ouchannel); inchannel.close (); // delete shard file.delete ();} // clear dosder file tempfile = nouveau fichier (serverpath + "/" + filemd5); if (tempfile.isdirectory () && tempfile.exists ()) {tempfile.delete ();} // fermer le flux outchannel.close (); réponse.setContentType ("text / html; charset = utf-8"); réponse.Getwriter ().Les grands points de rupture de fichiers se poursuivent
Sur la base de la mise en œuvre du téléchargement de blocs, il est très simple d'implémenter la transmission continue de point d'arrêt! ! !
l'extrémité avant:
// Point temporel 2: S'il y a un téléchargement de bloc, cette fonction est appelée avant chaque téléchargement de bloc // bloc: représente l'objet de bloc actuel beForesend: fonction (bloc) {// 1. Demandez si l'arrière-plan a enregistré le bloc actuel. S'il existe, sautez le fichier de blocs pour réaliser la fonction de transmission continue de point d'arrêt var Deferred = webuploader.deferred (); // demande si l'arrière-plan enregistre les informations du fichier. S'il a été sauvé, il sera ignoré. Si ce n'est pas le cas, le contenu de morceau sera envoyé $ .ajax ({type: "Post", URL: "$ {pageContext.request.contextPath} / uploadCheckServlet? Action = CheckChunk", Data: {// Le fichier Mark Unique FileMd5: filemd5, // the chunk chunk chunk: block.chunk, // lock.end-block.start},dataType:"json",success:function(response){if(response.ifExist){//The block exists, skip the block deferred.reject();}else{//The block does not exist or is incomplete, and resend the block content deferred.resolve();}}});//Carry the unique tag of the current file to the background, and let the background create Le répertoire qui enregistre le fichier bloque ce.owner.options.formdata.filemd5 = filemd5; return deferred.promise (); },Dans les coulisses:
// Vérifiez si le morceau existe ou enregistre privé VOID CheckChunk (HttpServLetRequest Request, HttpServletResponse Response) lance ioException, filenotFoundException {System.out.println ("checkchunk ..."); String filemd5 = request.getParamètre ("filemd5"); string chunk = request.getParamter ("chunk"); request.getParameter ("ChunkSize"); fichier checkFile = new File (serverPath + "/" + filemd5 + "/" + chunk); réponse.setContentType ("text / html; charset = utf-8"); // vérifier si le fichier existe et que la taille est cohérente si (checkFile.exists () && CheckFile.Length () == Integer.ParseInt (ChunkSize)) {Response.getWriter (). Write ("{/" Ifexist / ": 1}");} else {Response.getWriter (). Write ("{/" Ifexist / ": 0}");}}.Transfert de fichiers en quelques secondes
Avant toutes les demandes de blocs, la deuxième fonction de transfert peut être implémentée! ! !
l'extrémité avant:
beForeSendFile: function (file) {// Créer un deffar deferred = webuploader.deferred (); // 1. Calculez la marque unique du fichier, utilisé pour la transmission continue et la deuxième transmission (new Webuploader.uploader ()). MD5File (fichier, 0,5 * 1024 * 1024) .Progress (fonction (pourcentage) {$ ("#" + file.id) .Find ("div.state"). Val; $ ("#" + file.id) .find ("div.state"). $ .ajax ({type: "Post", URL: "$ {pageContex filemd5: filemd5}, dataType: "json", succès: fonction (réponse) {if (réponse.ifexist) {$ ("#" + file.id) .find ("div.state"). Text ("Soufflé avec succès"); Deferred.Resolve ();}}});}); // retourne devrérREDreturn Deferred.promise ();},Dans les coulisses:
// Vérifiez si les données MD5 du fichier sont liées à la requête FileCheck Private void (HttpServLetRequest de la base de données, HttpservletResponse Response) lance ioException, filenotFoundException {String fileMd5 = request.getParameter ("filemd5"); // simule la carte de database <string, string> database = new Hashmap <string, string> (); database.put ("576018603f4091782b68b78af85704a1", "01. Cours. Examen.itcast "); réponse.setContentType (" text / html; charset = utf-8 "); if (database.containsKey (fileMd5)) {réponse.getWriter (). Write (" {/ "ifexist /": 1} ");} else {réponse.getwriter ().Ce qui précède est un exemple d'explication du téléchargement de fichiers Javaweb et du téléchargement que l'éditeur vous a présenté (Cool File Teload Technology). J'espère que ce sera utile à tout le monde. Si vous avez des questions, veuillez me laisser un message et l'éditeur répondra à tout le monde à temps. Merci beaucoup pour votre soutien au site Web Wulin.com!