精选文章 SpringMVC文件夹上传解决方案

SpringMVC文件夹上传解决方案

作者:Mr_Zang666 时间: 2020-04-17 03:33:06
Mr_Zang666 2020-04-17 03:33:06

本人在2010年时使用swfupload为核心进行文件的批量上传的解决方案。见文章:WEB版一次选择多个文件进行批量上传(swfupload)的解决方案。

本人在2013年时使用plupload为核心进行文件的批量上传的解决方案。见文章:WEB版一次选择多个文件进行批量上传(Plupload)的解决方案

最近在学习百度的开源上传组件WebUploader,写了一些示例以记录。WebUploader的缺点是没有一个比较好的现成的界面,这个界面需要自己去实现。自由度高了一些。

WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件。在现代的浏览器里面能充分发挥HTML5的优势,同时又不摒弃主流IE浏览器,沿用原来的FLASH运行时,兼容IE6+,iOS 6+, android 4+。两套运行时,同样的调用方式,可供用户任意选用。浏览器支持ie6,ie7,ie8,ie9,ie10,ie11,firefox,chrome,edge。支持全平台操作系统:Windows,Mac,Linux支持文件夹上传下载,文件批量上传下载,层级目录保存。

 

关于WebUploader的功能说明:

 

大文件上传续传

支持超大文件上传(100G+)和续传,可以关闭浏览器,重启系统后仍然继续上传。
开源
提供ASP.NET,JSP,PHP示例和源代码,其中JSP提供MySQL,Oracle,SQL Server数据库的配置和示例代码。

分片、并发

分片与并发结合,将一个大文件分割成多块,并发上传,极大地提高大文件的上传速度。

当网络问题导致传输错误时,只需要重传出错分片,而不是整个文件。另外分片传输能够更加实时的跟踪上传进度。

预览、压缩

支持常用图片格式jpg,jpeg,gif,bmp,png预览与压缩,节省网络数据传输。

解析jpeg中的meta信息,对于各种orientation做了正确的处理,同时压缩后上传保留图片的所有原始meta数据。

多途径添加文件

支持文件多选,类型过滤,拖拽(文件&文件夹),图片粘贴功能。上传本地指定路径的文件,不需要通过点击按钮选择文件。

粘贴功能主要体现在当有图片数据在剪切板中时(截屏工具如QQ(Ctrl + ALT + A), 网页中右击图片点击复制),Ctrl + V便可添加此图片文件。

HTML5 & FLASH

兼容主流浏览器和低版本浏览器,接口一致,实现了两套运行时支持,用户无需关心内部用了什么内核。而且支持IE6,IE8浏览器。

同时Flash部分没有做任何UI相关的工作,方便不关心flash的用户扩展和自定义业务需求。

基于内存映射模式进行IO操作,充分发挥操作系统性能。
MD5秒传

 

当文件体积大、量比较多时,支持上传前做文件md5值验证,一致则可直接跳过。

如果服务端与前端统一修改算法,取段md5,可大大提升验证性能,耗时在20ms左右。

易扩展、可拆分

采用可拆分机制, 将各个功能独立成了小组件,可自由搭配。

采用AMD规范组织代码,清晰明了,方便高级玩家扩展。

文件夹上传

支持10万+级别的文件夹上传,续传。

支持层级目录结构保存,上传后能够将数据库层级信息保存在数据库中。
提供MySQL,Oracle,SQL Server数据库支持。

支持文件夹续传,在浏览器刷新,重启后仍然能够继续上传。

支持跨域上传。

PC端全平台支持
支持Windows,macOS,Linux。支持国产化操作系统,支持政务信息安全项目。
其中Windows支持低版本系统:Windows XP。
其中浏览器包括:IE6,IE7,IE8(x86,x64),IE9(x86,x64),IE10(x86,x64),IE11(x86,x64),360安全浏览器,360极速浏览器,QQ浏览器,搜狗浏览器,Maxthon(遨游)浏览器1.X,Maxthon(傲游)浏览器2.x,Firefox,Chrome,Opera 23+

 

一: 下面就是利用WebUploader组件,让客户一次选择多个文件,然后将选择的文件上传到服务器的批量文件解决方案。

让我们先来看看客户端的界面效果图。(多选文件,批量上传,上传进度显示)

 

说明:见上图WebUploader默认是3个线程一起并发上传文件。如果需要增加并发数,或是减少并发数。可以修改threads属性,这个属性就是允许的最大上传并发数。

 

                      

二:具体的代码与操作步骤:

 

第一步,要完成下面的示例,必须先准备好WebUploader组件。

1) WebUploader:大家可以访问WebUploader官方网站:http://www.webuploader.net,在这个网站上可以下载到组件与demo。

 

第二步,这个示例的目录结构如图:

1.主要目录结构

 SpringMVC文件夹上传解决方案1

2. 此示例中用到的js脚本文件与css文件。

  SpringMVC文件夹上传解决方案2

第三步,前台部分准备客户操作的WEB界面,如下[WebUploaderFileByBaidu2.aspx、UploaderFileByBaidu.ashx]

 

1)  前台客户端代码,其中WebUploaderFileByBaidu2.aspx的代码如下,WebUploaderFileByBaidu2.aspx.cs文件中只使用默认的代码,不用添加任何代码。

 

Html代码

 

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebUploaderFileByBaidu2.aspx.cs" Inherits="WebApplication1.WebUploaderFileByBaidu2" %>

    WebUploader文件上传示例

 

      

      

    

 

      

    

    

    

 

     

         var applicationPath = window.applicationPath === "" ? "" : window.applicationPath || "../../";

         // 文件上传         jQuery(function () {

             var $ = jQuery,

                 $list = $('#fileList'),

                 $btn = $('#ctlBtn'),

                 state = 'pending',

                 uploader;

             uploader = WebUploader.create({

                 // 不压缩image

                 resize: false,

 

                 // swf文件路径

                 swf: applicationPath + 'Script/webuploader/Uploader.swf',

 

                 // 文件接收服务端。

                 server: 'UploaderFileByBaidu.ashx',

 

                 // 选择文件的按钮。可选。

                 // 内部根据当前运行是创建,可能是input元素,也可能是flash.

                 pick: '#picker'

 

             });

 

             // 当有文件添加进来的时候

             uploader.on('fileQueued', function (file) {

 

                 $list.append('

' +

                     '

' + file.name + '

' +

                     '

等待上传...

' +

                 '

');

 

             });

 

             // 文件上传过程中创建进度条实时显示。

             uploader.on('uploadProgress', function (file, percentage) {

 

                 var $li = $('#' + file.id),

                     $percent = $li.find('.progress .progress-bar');

                 // 避免重复创建

                 if (!$percent.length) {

                     $percent = $('

' +

                       '

' +

                       '

' +

                     '

').appendTo($li).find('.progress-bar');

                 }

                 $li.find('p.state').text('上传中');

                 $percent.css('width', percentage * 100 + '%');

 

             });

 

             uploader.on('uploadSuccess', function (file) {

                 $('#' + file.id).find('p.state').text('已上传');

             });

 

             uploader.on('uploadError', function (file) {

                 $('#' + file.id).find('p.state').text('上传出错');

             });

 

             uploader.on('uploadComplete', function (file) {

                 $('#' + file.id).find('.progress').fadeOut();

             });

             uploader.on('all', function (type) {

                 if (type === 'startUpload') {

                     state = 'uploading';

                 } else if (type === 'stopUpload') {

                     state = 'paused';

                 } else if (type === 'uploadFinished') {

                     state = 'done';

                 }

                 if (state === 'uploading') {

                     $btn.text('暂停上传');

                 } else {

                     $btn.text('开始上传');

                 }

 

             });

 

             $btn.on('click', function () {

                 if (state === 'uploading') {

                     uploader.stop();

                 } else {

                     uploader.upload();

                 }

             });

         });

    

 

    

        

        文件上传示例:

         

  

    

    

    

        选择文件   

 

    

             

 

          

 

    

          开始上传

    

    

    

    

 

 

以上代码最后的显示结果如下图:

 SpringMVC文件夹上传解决方案3

 

 

2) 接收前端用户上传的文件,并把文件保存到指定目录中。UploaderFileByBaidu.ashx文件中使用默认的代码,不需要添加任何代码。UploaderFileByBaidu.ashx.cs文件的代码如下: 

using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Text;using System.Web;namespace WebApplication1

{

    /// 

    /// UploaderFileByBaidu 的摘要说明

    /// 

    public class UploaderFileByBaidu : IHttpHandler

 

    {

        public void ProcessRequest(HttpContext context)

        {

            context.Response.ContentEncoding = Encoding.UTF8;

            if (context.Request["REQUEST_METHOD"] == "OPTIONS") 

          {

                context.Response.End();

            }

 

            SaveFile();

        }

 

        /// 

        /// 文件保存操作

        /// 

        /// 

        private void SaveFile(string basePath = "~/Upload/Images/")

        {

    

             basePath = FileHelper.GetUploadPath();

            string Datedir = DateTime.Now.ToString("yy-MM-dd");

            string updir = basePath + "\\" + Datedir;

            string extname = string.Empty;

            string fullname = string.Empty;

            string filename = string.Empty;    

 

            HttpFileCollection files = System.Web.HttpContext.Current.Request.Files;

 

            if (files.Count == 0)

            {

                var result = "{\"jsonrpc\" : \"2.0\", \"error\" :  \"保存失败\",\"id\" :  \"id\"}";

                System.Web.HttpContext.Current.Response.Write(result);

            }

            if (!Directory.Exists(updir))

                Directory.CreateDirectory(updir);

 

            var suffix = files[0].ContentType.Split('/');

            var _suffix = suffix[1].Equals("jpeg", StringComparison.CurrentCultureIgnoreCase) ? "" : suffix[1];

            var _temp = System.Web.HttpContext.Current.Request["name"];

 

            if (!string.IsNullOrEmpty(_temp))

            {

                filename = _temp;

            }

            else

            {

                Random rand = new Random(24 * (int)DateTime.Now.Ticks);

                filename = rand.Next() + "." + _suffix;

            }

 

             fullname = string.Format("{0}\\{1}",updir , filename);

            files[0].SaveAs(fullname);

            var _result = "{\"jsonrpc\" : \"2.0\", \"result\" : null, \"id\" : \"" + filename + "\"}";

            System.Web.HttpContext.Current.Response.Write(_result);

 

        }

 

        public bool IsReusable

        {

 

            get

            {

                return false;

            }

        }

    }

}

 

 第四步:文件辅助类

///

///FileHelper 的摘要说明/// public class FileHelper

{

 

    public FileHelper()

    {

 

        //

        //TODO: 在此处添加构造函数逻辑

        //    }

 

    ///

    /// 获取上传目录

    ///

    ///

     public static string GetUploadPath()

        {

 

          string path = HttpContext.Current.Server.MapPath("~/");

          string dirname = GetDirName();

          string uploadDir = path + "\\" + dirname;

          CreateDir(uploadDir);

          return uploadDir;

        }

 

    ///

    /// 获取临时目录

    ///

    ///

     public static string GetTempPath()

     {

 

         string path = HttpContext.Current.Server.MapPath("~/");

         string dirname = GetTempDirName();

         string uploadDir = path + "\\" + dirname;

         CreateDir(uploadDir);

         return uploadDir;

     }

 

        private static string GetDirName()

        {

            return System.Configuration.ConfigurationManager.AppSettings["uploaddir"];

 

        }

 

        private static string GetTempDirName()

        {

            return System.Configuration.ConfigurationManager.AppSettings["tempdir"];

        }

 

    public static void CreateDir(string path)

        {

                if (!System.IO.Directory.Exists(path))

                {                 

 

                    System.IO.Directory.CreateDirectory(path);

                }

        }

}

 

第五步,Web.config文件配置信息。

  

      

  

 

  

    

    

  

 

  

    

 

    

     

    

  

    

    

      

        

      

    

  

后端代码逻辑大部分是相同的,目前能够支持MySQL,Oracle,SQL。在使用前需要配置一下数据库,可以参考我写的这篇文章:http://blog.ncmem.com/wordpress/2019/08/09/web%E5%A4%A7%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/ 
欢迎入群一起讨论“374992201”

勿删,copyright占位
分享文章到微博
分享文章到朋友圈

您可能感兴趣

  • 【时间序列】时间序列基本概念总结

    最近一直在接触时间序列,所以打算写一些有关时间序列的文章,预测部分会从规则开始、到传统模型、到机器学习、再到深度学习,此外也会介绍一些时间序列的基本概念,包括自相关、平稳性、滞后性、季节性等。 1.基本概念 1.1 时间序列预测 预测是商业中的常见统计任务,它可以为生产、运输和人员安排等决策提供信息,并为长期战略规划提供指导。预测是指在考虑到所有可用信息的前提下,包括历史数据和可以影响预测的...

  • Flink x Zeppelin ,Hive Streaming 实战解析

    行业解决方案、产品招募中!想赚钱就来传!>>> Flink 1.11 正式发布已经三周了,其中最吸引我的特性就是 Hive Streaming。正巧 Zeppelin-0.9-preview2 也在前不久发布了,所以就写了一篇 Zeppelin 上的 Flink Hive Streaming 的实战解析。本文主要从以下几部分跟大家分享: Hive Streaming 的意义 Checkpoi...

  • SQL Server安全机制–如何控制用户能够在报告中查看哪些数据

    介绍 ( Introduction ) A few years back, a client asked me to implement a quick and dirty “security mechanism” to control what data the myriad of users were able to view within their reports. There we...

  • 使用SQL Server事务复制将SQL Server数据库迁移到Azure SQL数据库

    In this guide, we’ll discuss more about migrating a SQL Server database to Azure SQL Database using SQL Server Transactional Replication. 在本指南中,我们将讨论有关使用SQL Server事务复制将SQL Server数据库迁移到Azure SQL数据库的...

  • fn_dblog_如何使用fn_dblog和fn_dump_dblog直接在SQL Server数据库中连续读取事务日志文件数据

    fn_dblog 大纲 (Outline) In this article, we’ll discuss how to read SQL Server transaction logs. This article should provide and insight into how the workload is being captured in the transaction log ...

  • SQL Server事务复制移动分发数据库–分步指南

    SQL Server replication is a relatively old high-availability solution part of the Microsoft world. In fact, there have not been any significant changes to this solution in the recent versions SQL v...

  • ssrs 数据分页_如何在SSRS中使用JSON数据

    ssrs 数据分页 In this article, we will explore the concept of using JSON data in SQL Server Reporting Services (SSRS). This usage concept will include a different approach than the usual methodologies ...

  • 新职业教育的三节课,凭什么做到今天这样

    历时7天、翻遍15个平台渠道、访谈25位参与课程的从业者、挖掘了136条推文的标题和内容,我们得到了12500字的拆解。可以点击右上角☝:收藏、分享、在看,不用担心看一半,找不到文章。 本文信息公开来源:三节课官方公众号、虎嗅网、36氪、深网、东方财富网、新榜、知乎、简书、增长黑盒、短书··· 我们认为,这可能比任何官方复盘更能诠释:「三节课」是如何在3年内,做到互联网职业教育(Almost...

华为云40多款云服务产品0元试用活动

免费套餐,马上领取!
CSDN

CSDN

中国开发者社区CSDN (Chinese Software Developer Network) 创立于1999年,致力为中国开发者提供知识传播、在线学习、职业发展等全生命周期服务。