Maison > Java > javaDidacticiel > le corps du texte

Explication détaillée du code de la fonction de téléchargement de fichiers utilisant la combinaison de Java et WebUploader

黄舟
Libérer: 2017-03-30 10:11:32
original
2323 Les gens l'ont consulté

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>
Copier après la connexion

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);
 }
}
Copier après la connexion

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 Miaozhuan

utilise

<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>
Copier après la connexion
  • pour générer un fichier liste de noms et afficher la progression du téléchargement en temps réel, Afficher les

    Vignettes

  • Ajouter une liste de fichiers p,

    <p id="fileList"></p>

  • Générer des vignettes et afficher la progression du téléchargement

// 生成缩略图和上传进度
uploader.on("fileQueued", function(file) {
  // 把文件信息追加到fileList的p中
  $("#fileList").append("<p id=&#39;" + file.id + "&#39;><img/><span>" + file.name + "</span><p><span class=&#39;percentage&#39;><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) + "%");
});
Copier après la connexion
  • Glisser-déposer le téléchargement, coller le téléchargement

  • Créer un glisser zone et styles définis :

<style type="text/css">
 #dndArea {
  width: 200px;
  height: 100px;
  border-color: red;
  border-style: dashed;
 }
</style>  
<!-- 创建用于拖拽的区域 -->
<p id="dndArea"></p>
Copier après la connexion
  • Ajouter la configuration de la zone DND (activer le glisser-déposer) dans la configuration de base

Réponses du bouclier en dehors de la zone de glisser

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,
  // 
 }  
);
Copier après la connexion
  • Téléchargement de fichiers bloqué

Le le front-end génère un

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
}  
);
Copier après la connexion
Surveillance du front-end les morceaux
  • peuvent être divisés en trois moments :

before-send-file : cette méthode est appelée avant que le fichier ne soit téléchargé (il ne sera appelé qu'avant le téléchargement d'un fichier).
  • Vous pouvez obtenir la chaîne md5 du fichier dans cette méthode comme nom de répertoire pour enregistrer le fichier fragmenté en arrière-plan <🎜. >

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

  • ajoute une balise d'état
 // 监听分块上传的时间点,断点续传
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() {
  }
 }
);
Copier après la connexion
enregistre le fichier

$("#fileList").append("<p id=&#39;" + file.id + "&#39;>
<img/>
<span>" + file.name + "</span>
<p>
<span class=&#39;state&#39;>
</span>
</p>
<p>
<span class=&#39;percentage&#39;>
</span>
</p>
</p>");
Copier après la connexion

Le front-end notifie l'action de fusion de fichiers
// 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);
    }
  }
Copier après la connexion
  • Front-end ajouté :

Nouvel ajout

Action de fusion :
// 通知合并分块
$.ajax(
  {
    type:"POST",
    url:"${pageContext.request.contextPath}/UploadActionServlet?action=mergeChunks",
    data:{
      fileMd5:fileMd5
    },
    success:function(response){
    }
  }
);
Copier après la connexion

Reprendre le point d'arrêt
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);
  }
}
Copier après la connexion
  • Ajouter une vérification avant d'envoyer la page frontale à vérifiez si les morceaux ont été téléchargés

Ajouter une vérification en action
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();
      }
Copier après la connexion

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!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!