zoukankan      html  css  js  c++  java
  • SpringMVC+Ajax实现文件批量上传和下载功能实例代码

    需求:

    文件批量上传,支持断点续传。

    文件批量下载,支持断点续传。

    使用JS能够实现批量下载,能够提供接口从指定url中下载文件并保存在本地指定路径中。

    服务器不需要打包。

    支持大文件断点下载。比如下载10G的文件。

    PC端全平台支持。Windows,macOS,Linux

    全浏览器支持。ie6,ie7,ie8,ie9,ie10,ie11,edge,firefox,chrome,safari

     

    这篇文章主要介绍了SpringMVC+Ajax实现文件批量上传和下载功能实例代码,代码分为上传form和上传ajax,具体实例代码大家参考下本文

    今天做了文件的上传下载,小小总结一下,基本的web项目建立及SpringMVC框架搭建此处不详细写出来了。

    上传form:

    <form id="uploadfiles" enctype="multipart/form-data">

        <input type="file" multiple="multiple" id="file_upload" name="file_upload" />

        <input type="button" value="上传" onclick="upload()" />

    </form>

    上传Ajax:

    <script type="text/javascript">

    /*

     * 上传文件

     */

    function upload(){

      var formData = new FormData($( "#uploadfiles" )[0]);

       $.ajax({

          type: "post",

          url: "./path/upload",

          dataType: "json",

          data: formData,

          /** 

           *必须false才会自动加上正确的Content-Type 

           */

          contentType : false,

          /** 

           * 必须false才会避开jQuery对 formdata 的默认处理 

           * XMLHttpRequest会对 formdata 进行正确的处理 

           */

          processData : false,

          success: function(data){//从后端返回数据进行处理

           if(data){

             alert("上传成功!");

           }else{

             alert("上传失败!");

           }

          },

          error: function(err) {//提交出错

            $("#msg").html(JSON.stringify(err));//打出响应信息

            alert("服务器无响应");

           }

         });

    }

    </script>

     

    上传文件块

    <%@page language="java" import="up6.DBFile" pageEncoding="UTF-8"%>

    <%@page contentType="text/html;charset=UTF-8"%>

    <%@page import="up6.FileBlockWriter" %>

    <%@page import="up6.XDebug" %>

    <%@page import="up6.*" %>

    <%@page import="up6.biz.*" %>

    <%@page import="org.apache.commons.fileupload.FileItem" %>

    <%@page import="org.apache.commons.fileupload.FileItemFactory" %>

    <%@page import="org.apache.commons.fileupload.FileUploadException" %>

    <%@page import="org.apache.commons.fileupload.disk.DiskFileItemFactory" %>

    <%@page import="org.apache.commons.fileupload.servlet.ServletFileUpload" %>

    <%@page import="org.apache.commons.lang.*" %>

    <%@page import="java.net.URLDecoder"%>

    <%@page import="java.util.Iterator"%>

    <%@page import="net.sf.json.JSONObject"%>

    <%@page import="java.util.List"%>

    <% out.clear();

    String uid          = request.getHeader("uid");//

    String id           = request.getHeader("id");

    String lenSvr       = request.getHeader("lenSvr");

    String lenLoc       = request.getHeader("lenLoc");

    String blockOffset  = request.getHeader("blockOffset");

    String blockSize    = request.getHeader("blockSize");

    String blockIndex   = request.getHeader("blockIndex");

    String blockMd5     = request.getHeader("blockMd5");

    String complete     = request.getHeader("complete");

    String pathSvr      = "";

     

    //参数为空

    if(  StringUtils.isBlank( uid )

        || StringUtils.isBlank( id )

        || StringUtils.isBlank( blockOffset ))

    {

        XDebug.Output("param is null");

        return;

    }

     

    // Check that we have a file upload request

    boolean isMultipart = ServletFileUpload.isMultipartContent(request);

    FileItemFactory factory = new DiskFileItemFactory();  

    ServletFileUpload upload = new ServletFileUpload(factory);

    List files = null;

    try

    {

        files = upload.parseRequest(request);

    }

    catch (FileUploadException e)

    {// 解析文件数据错误  

        out.println("read file data error:" + e.toString());

        return;

      

    }

     

    FileItem rangeFile = null;

    // 得到所有上传的文件

    Iterator fileItr = files.iterator();

    // 循环处理所有文件

    while (fileItr.hasNext())

    {

        // 得到当前文件

        rangeFile = (FileItem) fileItr.next();

        if(StringUtils.equals( rangeFile.getFieldName(),"pathSvr"))

        {

            pathSvr = rangeFile.getString();

            pathSvr = PathTool.url_decode(pathSvr);

        }

    }

     

    boolean verify = false;

    String msg = "";

    String md5Svr = "";

    long blockSizeSvr = rangeFile.getSize();

    if(!StringUtils.isBlank(blockMd5))

    {

        md5Svr = Md5Tool.fileToMD5(rangeFile.getInputStream());

    }

     

    verify = Integer.parseInt(blockSize) == blockSizeSvr;

    if(!verify)

    {

        msg = "block size error sizeSvr:" + blockSizeSvr + "sizeLoc:" + blockSize;

    }

     

    if(verify && !StringUtils.isBlank(blockMd5))

    {

        verify = md5Svr.equals(blockMd5);

        if(!verify) msg = "block md5 error";

    }

     

    if(verify)

    {

        //保存文件块数据

        FileBlockWriter res = new FileBlockWriter();

        //仅第一块创建

        if( Integer.parseInt(blockIndex)==1) res.CreateFile(pathSvr,Long.parseLong(lenLoc));

        res.write( Long.parseLong(blockOffset),pathSvr,rangeFile);

        up6_biz_event.file_post_block(id,Integer.parseInt(blockIndex));

       

        JSONObject o = new JSONObject();

        o.put("msg""ok");

        o.put("md5", md5Svr);  

        o.put("offset", blockOffset);//基于文件的块偏移位置

        msg = o.toString();

    }

    rangeFile.delete();

    out.write(msg);

    %>

     

    下载的jsp页面代码根据需求不同自己设计,这里给出jsp代码:

    <%@page language="java" import="java.util.*" pageEncoding="UTF-8"%>

    <%@page contentType="text/html;charset=UTF-8"%>

    <%@page import="up6.*" %>

    <%@page import="up6.model.*" %>

    <%@page import="java.nio.*" %>

    <%@page import="java.nio.channels.*" %>

    <%@page import="java.net.URLDecoder" %>

    <%@page import="java.net.URLEncoder" %>

    <%@page import="org.apache.commons.lang.*" %>

    <%@page import="com.google.gson.FieldNamingPolicy" %>

    <%@page import="com.google.gson.Gson" %>

    <%@page import="com.google.gson.GsonBuilder" %>

    <%@page import="com.google.gson.annotations.SerializedName" %>

    <%@page import="java.io.*" %>

    <% out.clear();

    String path = request.getContextPath();

    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

     

    String fid          = request.getHeader("id");

    String blockIndex   = request.getHeader("blockIndex");//基于1

    String blockOffset = request.getHeader("blockOffset");//块偏移,相对于整个文件

    String blockSize    = request.getHeader("blockSize");//块大小(当前需要下载的大小)

    String pathSvr      = request.getHeader("pathSvr");//文件在服务器的位置

    pathSvr             = PathTool.url_decode(pathSvr);

     

    if (  StringUtils.isBlank(fid)

        ||StringUtils.isBlank(blockIndex)

        ||StringUtils.isEmpty(blockOffset)

        ||StringUtils.isBlank(blockSize)

        ||StringUtils.isBlank(pathSvr))

    {

        response.setStatus(500);

        response.setHeader("err","参数为空");

        return;

    }

    File f = new File(pathSvr);

     

    //文件不存在

    if(!f.exists())

    {

        response.setStatus(500);

        OutputStream os = response.getOutputStream();

        System.out.println(String.format("%s 文件不存在",pathSvr));

        os.close();

        return;

    }

     

    long fileLen = f.length();

     

    response.setContentType("application/x-download");

    response.setHeader("Pragma","No-cache"); 

    response.setHeader("Cache-Control","no-cache");

    response.addHeader("Content-Length",blockSize); 

    response.setDateHeader("Expires", 0);

     

    OutputStream os = response.getOutputStream();

    try

    {

        RandomAccessFile raf = new RandomAccessFile(pathSvr,"r");

       

        int readToLen = Integer.parseInt(blockSize);

        int readLen = 0;

        raf.seek( Long.parseLong(blockOffset) );//定位索引

        byte[] data = newbyte[1048576];

       

        while( readToLen > 0 )

        {

            readLen = raf.read(data,0,Math.min(1048576,readToLen) );

            readToLen -= readLen;

            os.write(data, 0, readLen);

           

        }

        os.flush();

        os.close();

        raf.close();

        os = null;

        response.flushBuffer();

       

        out.clear();

        out = pageContext.pushBody();

    }

    catch(Exception e)

    {

        response.setStatus(500);

        os.close();

        out.close();

        e.printStackTrace();

    }

    finally

    {  

        if(os != null)

        {

            os.close();    

            os = null;

        }

        out.clear();

        out = pageContext.pushBody();

    }%>

    这里我们进行了优化,下载文件时将不在服务器打包。这个优化对于大型文件的下载来说大幅度提升了效率,而且节省了服务器的资源。当下载用户比较多的时候,服务器将不会出现打包多个文件导致磁盘空间被占满的情况。

     

    下载页面如果用Ajax提交请求的话要注意:ajax函数的返回类型只有xml、text、json、html等类型,没有“流”类型,所以我们要实现ajax下载,不能够使用相应的ajax函数进行文件下载。但可以用js生成一个form,用这个form提交参数,并返回“流”类型的数据。

    例子:

    function download(){

        var form=$("<form>");//定义一个form表单

        form.attr("style","display:none");

        form.attr("target","");

        form.attr("method","post");

        form.attr("action","./path/download");//请求url

        var input1=$("<input>");

        input1.attr("type","hidden");

        input1.attr("name","rows");//设置属性的名字

        input1.attr("value",“test”);//设置属性的值

        $("body").append(form);//将表单放置在web中

        form.append(input1);

        form.submit();//表单提交      

                  }

     

    总结

    以上所述是小编给大家介绍的SpringMVC+Ajax实现文件批量上传和下载功能实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。

     

    批量上传效果:

     

    批量下载效果

     

    网上例子:http://blog.ncmem.com/wordpress/2019/08/28/java批量下载/


  • 相关阅读:
    发现个atan2的正确使用方式
    Forward+ Shading架构
    fatal: unable to connect to gitee.com: gitee.com[0: 180.97.125.228]: errno=Unknown error 解决方案
    HDFS HA(高可用性)集群规划
    如何使用RTP引擎对语音编码进行转码
    关于 Angular 应用 tsconfig.json 中的 target 属性
    浅谈 Orbeon form builder 的权限控制
    关于 Angular 应用 tsconfig.json 中的 lib 属性
    orbeon form 通过 url 的方式同第三方应用集成的开发明细
    orbeon form 的配置介绍
  • 原文地址:https://www.cnblogs.com/xproer/p/11543690.html
Copyright © 2011-2022 走看看