Cet article présente principalement Java combiné avec WebUploader pour implémenter le Fileupload Fonction, le code est simple et facile à comprendre, très bon, et a une valeur de référence. Les amis qui en ont besoin peuvent s'y référer
J'ai aussi rencontré le problème du téléchargement de fichiers lorsque j'écrivais un petit projet avant. , mais je n'ai pas trouvé de bonne solution. Bien que j'ai vu WebUploader lorsque je cherchais diverses solutions en ligne, je ne suis pas entré plus en détail cette fois
Téléchargement et enregistrement de fichiers simples et de données normales
jsp page :
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form action="${pageContext.request.contextPath }/FileUploadServlet" method="post" enctype="multipart/form-data"> 文件:<input type="file" value="请选择文件" name="file" /> <br/> 信息:<input type="text" name="info" /> <br/> <input type="submit" value="提交" /> </form> </body> </html>
servlet :
package com.yihengliu.web.action; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.io.FileUtils; /** * Servlet user to accept file upload */ public class FileUploadServlet extends HttpServlet { private static final long serialVersionUID = 1L; private String serverPath = "e:/"; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().append("Served at: ").append(request.getContextPath()); System.out.println("进入后台..."); // 1.创建DiskFileItemFactory对象,配置缓存用 DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory(); // 2. 创建 ServletFileUpload对象 ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory); // 3. 设置文件名称编码 servletFileUpload.setHeaderEncoding("utf-8"); // 4. 开始解析文件 try { List<FileItem> items = servletFileUpload.parseRequest(request); for (FileItem fileItem : items) { if (fileItem.isFormField()) { // >> 普通数据 String info = fileItem.getString("utf-8"); System.out.println("info:" + info); } else { // >> 文件 // 1. 获取文件名称 String name = fileItem.getName(); // 2. 获取文件的实际内容 InputStream is = fileItem.getInputStream(); // 3. 保存文件 FileUtils.copyInputStreamToFile(is, new File(serverPath + "/" + name)); } } } catch (Exception e) { e.printStackTrace(); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
Utilisez le composant WebUploader pour télécharger
Partage, concurrence, aperçu, compression, plusieurs façons de ajouter des dossiers (fichiers Sélection multiple, glisser-déposer, etc.), le style de page Miaozhuanutilise
<html> <title>使用webuploader上传</title> <!-- 1.引入文件 --> <link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath }/js/webuploader.css" rel="external nofollow" > <script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery-2.1.4.min.js"></script> <script type="text/javascript" src="${pageContext.request.contextPath }/js/webuploader.js"></script> </head> <body> <!-- 2.创建页面元素 --> <p id="upload"> <p id="filePicker">文件上传</p> </p> <!-- 3.添加js代码 --> <script type="text/javascript"> var uploader = WebUploader.create( { swf:"${pageContext.request.contextPath }/js/Uploader.swf", server:"${pageContext.request.contextPath }/FileUploadServlet", pick:"#filePicker", auto:true } ); </script> </body> </html>
<p id="fileList"></p>
// 生成缩略图和上传进度 uploader.on("fileQueued", function(file) { // 把文件信息追加到fileList的p中 $("#fileList").append("<p id='" + file.id + "'><img/><span>" + file.name + "</span><p><span class='percentage'><span></p></p>") // 制作缩略图 // error:不是图片,则有error // src:代表生成缩略图的地址 uploader.makeThumb(file, function(error, src) { if (error) { $("#" + file.id).find("img").replaceWith("<span>无法预览 </span>"); } else { $("#" + file.id).find("img").attr("src", src); } }); } ); // 监控上传进度 // percentage:代表上传文件的百分比 uploader.on("uploadProgress", function(file, percentage) { $("#" + file.id).find("span.percentage").text(Math.round(percentage * 100) + "%"); });
<style type="text/css"> #dndArea { width: 200px; height: 100px; border-color: red; border-style: dashed; } </style> <!-- 创建用于拖拽的区域 --> <p id="dndArea"></p>
Activer la fonction de collage
var uploader = WebUploader.create( { swf:"${pageContext.request.contextPath }/js/Uploader.swf", server:"${pageContext.request.contextPath }/FileUploadServlet", pick:"#filePicker", auto:true, // 开启拖拽 dnd:"#dndArea", // 屏蔽拖拽区域外的响应 disableGlobalDnd:true, // } );
md5 basé sur le fichier qui doit être envoyé La chaîne est envoyée à l'arrière-plan, et l'arrière-plan crée un dossier nommé d'après la chaîne md5. end envoie le fichier en morceaux et envoie le numéro de série du bloc de fichiers à l'arrière-plan. Après avoir reçu le fichier, l'arrière-plan l'enregistre en fonction du nom du numéro de série. Une fois le front-end envoyé, il informe l'arrière-plan de fusionner les fichiers.
Configuration du front-end, s'il faut activer le chunking, la taille du chunk, le nombre de threads, etc.// 上传基本配置 var uploader = WebUploader.create( { swf:"${pageContext.request.contextPath }/js/Uploader.swf", server:"${pageContext.request.contextPath }/FileUploadServlet", pick:"#filePicker", auto:true, dnd:"#dndArea", disableGlobalDnd:true, paste:"#uploader", // 分块上传设置 // 是否分块 chunked:true, // 每块文件大小(默认5M) chunkSize:5*1024*1024, // 开启几个并非线程(默认3个) threads:3, // 在上传当前文件时,准备好下一个文件 prepareNextFile:true } );
before-send : Cette méthode est appelée avant le téléchargement de chaque fichier en plusieurs parties (appelée avant chaque téléchargement en plusieurs parties).
Vous pouvez envoyer la chaîne md5 en arrière-plan dans cette méthode, et l'arrière-plan jugera s'il y a déjà un bloc et décidera s'il doit l'envoyer pour réaliser la fonction de reprise de la transmission à un point d'arrêt
after-send-file : Cette méthode est appelée une fois que tous les fichiers ont été téléchargés sans erreur (appelée une fois que tous les téléchargements en plusieurs parties sont terminés).
Vous pouvez demander à l'arrière-plan de fusionner tous les morceaux dans cette méthode
Le front-end récupère la chaîne md5 du fichier et l'envoie à l'arrière-plan , la réception en arrière-plan crée un dossier si le dossier n'existe pas, enregistre le fichier envoyé en morceaux
// 监听分块上传的时间点,断点续传 var fileMd5; WebUploader.Uploader.register({ "before-send-file":"beforeSendFile", "before-send":"beforeSend", "after-send-file":"afterSendFile" },{ beforeSendFile:function(file) { // 创建一个deffered,用于通知是否完成操作 var deferred = WebUploader.Deferred(); // 计算文件的唯一标识,用于断点续传和妙传 (new WebUploader.Uploader()).md5File(file, 0, 5*1024*1024) .progress(function(percentage){ $("#"+file.id).find("span.state").text("正在获取文件信息..."); }) .then(function(val) { fileMd5 = val; $("#" + file.id).find("span.state").text("成功获取文件信息"); // 放行 deferred.resolve(); }); // 通知完成操作 return deferred.promise(); }, beforeSend:function() { var deferred = WebUploader.Deferred(); // 发送文件md5字符串到后台 this.owner.options.formData.fileMd5 = fileMd5; deferred.resolve(); return deferred.promise(); }, afterSendFile:function() { } } );
$("#fileList").append("<p id='" + file.id + "'> <img/> <span>" + file.name + "</span> <p> <span class='state'> </span> </p> <p> <span class='percentage'> </span> </p> </p>");
// 4. 开始解析文件 // 文件md5获取的字符串 String fileMd5 = null; // 文件的索引 String chunk = null; try { List<FileItem> items = servletFileUpload.parseRequest(request); for (FileItem fileItem : items) { if (fileItem.isFormField()) { // >> 普通数据 String fieldName = fileItem.getFieldName(); if ("info".equals(fieldName)) { String info = fileItem.getString("utf-8"); System.out.println("info:" + info); } if ("fileMd5".equals(fieldName)) { fileMd5 = fileItem.getString("utf-8"); System.out.println("fileMd5:" + fileMd5); } if ("chunk".equals(fieldName)) { chunk = fileItem.getString("utf-8"); System.out.println("chunk:" + chunk); } } else { // >> 文件 /*// 1. 获取文件名称 String name = fileItem.getName(); // 2. 获取文件的实际内容 InputStream is = fileItem.getInputStream(); // 3. 保存文件 FileUtils.copyInputStreamToFile(is, new File(serverPath + "/" + name));*/ // 如果文件夹没有创建文件夹 File file = new File(serverPath + "/" + fileMd5); if (!file.exists()) { file.mkdirs(); } // 保存文件 File chunkFile = new File(serverPath + "/" + fileMd5 + "/" + chunk); FileUtils.copyInputStreamToFile(fileItem.getInputStream(), chunkFile); } }
Front-end ajouté :
Nouvel ajout
Action de fusion :// 通知合并分块 $.ajax( { type:"POST", url:"${pageContext.request.contextPath}/UploadActionServlet?action=mergeChunks", data:{ fileMd5:fileMd5 }, success:function(response){ } } );
package com.yihengliu.web.action; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.UUID; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 合并上传文件 */ public class UploadActionServlet extends HttpServlet { private static final long serialVersionUID = 1L; private String serverPath = "e:/"; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("进入合并后台..."); String action = request.getParameter("action"); if ("mergeChunks".equals(action)) { // 获得需要合并的目录 String fileMd5 = request.getParameter("fileMd5"); // 读取目录所有文件 File f = new File(serverPath + "/" + fileMd5); File[] fileArray = f.listFiles(new FileFilter() { // 排除目录,只要文件 @Override public boolean accept(File pathname) { if (pathname.isDirectory()) { return false; } return true; } }); // 转成集合,便于排序 List<File> fileList = new ArrayList<File>(Arrays.asList(fileArray)); // 从小到大排序 Collections.sort(fileList, new Comparator<File>() { @Override public int compare(File o1, File o2) { if (Integer.parseInt(o1.getName()) < Integer.parseInt(o2.getName())) { return -1; } return 1; } }); // 新建保存文件 File outputFile = new File(serverPath + "/" + UUID.randomUUID().toString() + ".zip"); // 创建文件 outputFile.createNewFile(); // 输出流 FileOutputStream fileOutputStream = new FileOutputStream(outputFile); FileChannel outChannel = fileOutputStream.getChannel(); // 合并 FileChannel inChannel; for (File file : fileList) { inChannel = new FileInputStream(file).getChannel(); inChannel.transferTo(0, inChannel.size(), outChannel); inChannel.close(); // 删除分片 file.delete(); } // 关闭流 fileOutputStream.close(); outChannel.close(); // 清除文件加 File tempFile = new File(serverPath + "/" + fileMd5); if (tempFile.isDirectory() && tempFile.exists()) { tempFile.delete(); } System.out.println("合并文件成功"); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
Ajouter une vérification avant d'envoyer la page frontale à vérifiez si les morceaux ont été téléchargés
beforeSend:function(block) { var deferred = WebUploader.Deferred(); // 支持断点续传,发送到后台判断是否已经上传过 $.ajax( { type:"POST", url:"${pageContext.request.contextPath}/UploadActionServlet?action=checkChunk", data:{ // 文件唯一表示 fileMd5:fileMd5, // 当前分块下标 chunk:block.chunk, // 当前分块大小 chunkSize:block.end-block.start }, dataType:"json", success:function(response) { if(response.ifExist) { // 分块存在,跳过该分块 deferred.reject(); } else { // 分块不存在或不完整,重新发送 deferred.resolve(); } } } ); // 发送文件md5字符串到后台 this.owner.options.formData.fileMd5 = fileMd5; return deferred.promise(); }
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!