原因

近日,自己的服务器每次上传文件都感觉比较麻烦,所以想着自己动手搞一个文件上传和下载的服务.

实现的功能

  1. 大文件分片上传
  2. 文件下载
  3. 显示目录
  4. 新建文件夹

项目前的准备

  1. 技术采用了uploader 和spring的技术
  2. uploader 相关包的下载 如下:
  3. maven 相关依赖
<build><!--声明并引入子项目共有的插件--><!--        <pluginManagement>--><plugins><!--java maven的打包插件--><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>1.5.3.RELEASE</version><configuration><mainClass>com.xiaobo.Star</mainClass></configuration><executions><execution><goals><goal>repackage</goal></goals></execution></executions></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.5.1</version> <!-- or newer version --><configuration><source>1.8</source> <!-- depending on your project --><target>1.8</target> <!-- depending on your project --><annotationProcessorPaths><path><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version></path><!-- other annotation processors --></annotationProcessorPaths></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-assembly-plugin</artifactId><version>3.2.0</version><configuration><archive><manifest><!--指定入口文件的位置--><mainClass>com.xiaobo.Star</mainClass></manifest></archive><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs></configuration></plugin></plugins></build><dependencies><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-api</artifactId><version>2.17.1</version></dependency><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.17.1</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.3.1.RELEASE</version><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-autoconfigure</artifactId><version>2.3.1.RELEASE</version></dependency><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.1</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.4</version></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpcore</artifactId><version>4.4.10</version></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.6</version></dependency></dependencies>

开始飙代码

  1. 前端html代码
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>webuploader</title>
</head>
<!--引入CSS-->
<link rel="stylesheet" type="text/css" href="webuploader.css">
<script src="jquery-1.11.1.js"></script>
<script src="webuploader.js"></script>
<style>#upload-container, #upload-list {width: 500px;margin: 0 auto;}#upload-container {cursor: pointer;border-radius: 15px;background: #EEEFFF;height: 200px;}#upload-list {height: 800px;border: 1px solid #EEE;border-radius: 5px;margin-top: 10px;padding: 10px 20px;}#upload-container > span {widows: 100%;text-align: center;color: gray;display: block;padding-top: 15%;}.upload-item {margin-top: 5px;padding-bottom: 5px;border-bottom: 1px dashed gray;}.percentage {height: 5px;background: green;}.btn-delete, .btn-retry {cursor: pointer;color: gray;}.btn-delete:hover {color: orange;}.btn-retry:hover {color: green;}.fileImage {background-image: url("images/file.png");background-repeat: no-repeat;background-size: 25px 25px;height: 25px;width: 400px;cursor: pointer;overflow: hidden visible;}.fileFont {margin-left: 30px;margin-top: 50px;overflow: hidden;weight: auto;word-break: normal;white-space: pre-wrap;word-wrap: break-word;overflow: hidden;}.directoryImage {background-image: url("images/directory.png");background-repeat: no-repeat;background-size: 25px 25px;height: 25px;width: 400px;cursor: pointer;overflow: hidden visible;}.directoryFont {margin-left: 30px;margin-top: 50px}.upperLevel {height: 40px;cursor: pointer;float: left;}.createFile {height: 40px;cursor: pointer;float: right;}.warnMessage{position: absolute;left: 42%;top: 20px;color: #00FF00;font-family: 'Georgia,Serif';font-style: oblique;display: none;}</style>
<! --引入JS-->
<body>
<div style="clear: both;width: 80%;height:10px;margin:0 auto"><div style="float: left;width: 40%"><div id="upload-container""><span>点击或将文件拖拽至此上传</span></div><div id="upload-list"></div>
</div>
<div style="width: 40%;float: right;padding: 100px;"><div style="width: 400px;height: 40px;clear: both"><div class="upperLevel">上一级</div><div class="createFile">新建文件夹</div></div><div id="filePath"></div>
</div>
</div><button id="picker" style="display: none;">点击上传文件</button><div class="warnMessage"><div>提示信息</div>
</div>
</body><script>var absolutely = '/'getPath()function getPath(){$.ajax({type : "GET",url : 'http://localhost:8080/getFilePath?path='+absolutely,success : function(message){console.log(message);if (message.code == 200){listFile(message)showWarnMessage('获取列表成功')}}});}function showWarnMessage(message){var warnMessage = $(".warnMessage");warnMessage.html("<div style='display: block'}>"+message+"<div>")warnMessage.slideDown(2000);setTimeout(function(){warnMessage.slideUp(2000);},1000);}function createFile(filename){$.ajax({type : "GET",url : 'http://localhost:8080/createFile?path='+absolutely+filename,success : function(message){// console.log(message);if (message.code == 200){showWarnMessage('创建文件成功')}}});}function download(filename){var url = 'http://localhost:8080/download'var form = $("<form></form>").attr("action", url).attr("method", "get");form.append($("<input></input>").attr("type", "hidden").attr("name", "path").attr("value", absolutely+filename));form.appendTo('body').submit().remove();}function listFile(message){var file = '<div id="listFile">'for (let filePath of message.data.files){file += '<div class="fileImage"> <span class="fileFont">'+filePath+'</span></div>'}for (let filePath of message.data.directory){file += '<div class="directoryImage"> <span class="directoryFont">'+filePath+'</span></div>'}file +="</div>"$('#filePath').html(file)}$('body').on('click','#filePath .directoryImage',function (evnet){let text = $(this).text().trim()absolutely +=text +'/'console.log(absolutely)var name = absolutelygetPath()})$('body').on('click','#filePath .fileImage',function (evnet){let name = $(this).text()console.log(this.innerHTML)// let text = this.text();var r = confirm("确定下载文件: "+ name)if (r == true) {console.log("开始下载")download(name.trim())}})$('.upperLevel').click(function(event) {var name = absolutely.substring(absolutely.lastIndexOf('/'))absolutely = namegetPath()});$('.createFile').click(function(event) {var txt;var fileName = prompt("请输入文件夹的名称:", "11");if (fileName != null || fileName.trim() != "") {createFile(fileName)getPath()}});$('#upload-container').click(function(event) {$("#picker").find('input').click();});var uploader = WebUploader.create({auto: true,// 选完文件后,是否自动上传。swf: 'Uploader.swf',// swf文件路径server: 'http://localhost:8080/upload',// 文件接收服务端。dnd: '#upload-container',pick: '#picker',// 内部根据当前运行是创建,可能是input元素,也可能是flash. 这里是div的idmultiple: true, // 选择多个chunked: true,// 开启分片上传。threads: 20, // 上传并发数。允许同时最大上传进程数。method: 'POST', // 文件上传方式,POST或者GET。fileSizeLimit: 1024*1024*1024*10*1024, //验证文件总大小是否超出限制, 超出则不允许加入队列。fileSingleSizeLimit: 1024*1024*1024, //验证单个文件大小是否超出限制, 超出则不允许加入队列。fileVal:'upload', // [默认值:'file'] 设置文件上传域的name。formData: { "path": absolutely}});uploader.on("beforeFileQueued", function(file,data) {console.log(file); // 获取文件的后缀});uploader.on( 'uploadBeforeSend', function( block, data ) {// block为分块数据。// file为分块对应的file对象。var file = block.file;// 修改data可以控制发送哪些携带数据。data.path = absolutely;});uploader.on('fileQueued', function(file) {// 选中文件时要做的事情,比如在页面中显示选中的文件并添加到文件列表,获取文件的大小,文件类型等console.log(file.ext); // 获取文件的后缀console.log(file.size);// 获取文件的大小console.log(file.name);var html = '<div class="upload-item"><span>文件名:'+file.name+'</span><span data-file_id="'+file.id+'" class="btn-delete">删除</span><span data-file_id="'+file.id+'" class="btn-retry">重试</span><div class="percentage '+file.id+'" style="width: 0%;"></div></div>';$('#upload-list').append(html);uploader.md5File( file )//大文件秒传// 及时显示进度.progress(function(percentage) {console.log('Percentage:', percentage);})// 完成.then(function(val) {console.log('md5 result:', val);});});uploader.on('uploadProgress', function(file, percentage) {console.log(percentage * 100 + '%');var width = $('.upload-item').width();$('.'+file.id).width(width*percentage);});uploader.on('uploadSuccess', function(file, response) {console.log(file.id+"传输成功");getPath()// showWarnMessage('上传文件成功')});uploader.on('uploadError', function(file) {console.log(file);console.log(file.id+'upload error')showWarnMessage('上传文件失败')});$('#upload-list').on('click', '.upload-item .btn-delete', function() {// 从文件队列中删除某个文件idfile_id = $(this).data('file_id');// uploader.removeFile(file_id); // 标记文件状态为已取消uploader.removeFile(file_id, true); // 从queue中删除console.log(uploader.getFiles());});$('#upload-list').on('click', '.btn-retry', function() {uploader.retry($(this).data('file_id'));});uploader.on('uploadComplete', function(file) {console.log(uploader.getFiles());});</script>
</html>
  1. 后端上传代码
@RequestMapping("/upload")@ResponseBody@CrossOriginpublic ApiResponse upload(HttpServletRequest request, HttpServletResponse response, @RequestParam MultipartFile[] myfiles) {return fileService.upload1(request, response);}public ApiResponse upload1(HttpServletRequest request, HttpServletResponse response) {if (ServletFileUpload.isMultipartContent(request)) {String chunks = request.getParameter("chunks");MultipartFile uploadFile = ((MultipartHttpServletRequest) request).getFileMap().get("upload");// byte 数组byte[] bytes = new byte[1024];// 获取文件名String name = request.getParameter("name");String path = request.getParameter("path");// 判断是否是大文件开启 分片上传if (chunks == null) {log.warn(" 文件: " + name + "开始上传");System.out.println(" 文件: " + name + "开始上传");InputStream inputStream = null;File file = null;BufferedOutputStream bw = null;try {inputStream = uploadFile.getInputStream();file = new File(filePath + path + "\\" + name);System.out.println(filePath + path + "\\" + name);if (!file.exists()) {bw = new BufferedOutputStream(new FileOutputStream(file));file.createNewFile();int temp = 0;while ((temp = inputStream.read(bytes)) != -1) {bw.write(bytes, 0, temp);bw.flush();}bw.flush();log.warn(filePath + path + "\\" + name + ": 文件上传成功");System.out.println(filePath + path + "\\" + name + ": 文件上传成功");} else {// 存在抛出异常response.getWriter().write("文件名已存在" + name);response.reset();log.error("文件名已存在" + name);System.out.println("文件名已存在" + name);}} catch (IOException e) {e.printStackTrace();} finally {try {if (inputStream != null) {inputStream.close();}if (bw != null) {bw.close();}} catch (IOException e) {e.printStackTrace();}}} else {String chunk = request.getParameter("chunk");InputStream inputStream = null;File file = null;BufferedOutputStream bw = null;String[] fileNames = name.split("\\.");StringBuilder fileName = new StringBuilder();for (int i = 0; i < fileNames.length - 1; i++) {fileName.append(fileNames[i]);if (i < fileNames.length - 2) {fileName.append(".");}}String fileFuffix = fileNames[fileNames.length - 1];String tempName = filetemp + "\\" + fileName;try {inputStream = uploadFile.getInputStream();file = new File(tempName + "$%" + chunk);log.warn(" 文件: " + tempName + "$%" + chunk + "开始上传");System.out.println(" 文件: " + tempName + "$%" + chunk + "开始上传");if (!file.exists()) {bw = new BufferedOutputStream(new FileOutputStream(file));file.createNewFile();int temp = 0;while ((temp = inputStream.read(bytes)) != -1) {bw.write(bytes, 0, temp);bw.flush();}bw.flush();} else {// 存在抛出异常
//                        log.warn("临时文件已存在" + tempName + "$%" + chunk);System.out.println("临时文件已存在" + tempName + "$%" + chunk);}if (Integer.parseInt(chunks) - 1 == Integer.parseInt(chunk)) {log.warn(filePath + "\\" + fileName + "." + fileFuffix + ": 开始合并");System.out.println(filePath + "\\" + fileName + "." + fileFuffix + ": 开始合并");if (mergeFile(filePath, chunks, path, fileName.toString(), fileFuffix).equals("合并失败")) {log.error("上传文件: " + name + "失败");System.out.println("上传文件: " + name + "失败");return ApiResponse.FAIL("合并失败");}log.warn(filePath + name + ": 文件上传成功");System.out.println(filePath + name + ": 文件上传成功");}} catch (Exception e) {e.printStackTrace();log.error("上传文件: " + name + "失败");System.out.println("上传文件: " + name + "失败");} finally {try {if (inputStream != null) {inputStream.close();}if (bw != null) {bw.close();}} catch (IOException e) {e.printStackTrace();log.error("上传文件: " + name + "中 流关闭失败");System.out.println("上传文件: " + name + "中 流关闭失败");}}}}return ApiResponse.OK("上传成功");}
  1. 后台下载接口
@RequestMapping("/download")@ResponseBody@CrossOriginpublic void download(HttpServletRequest request, HttpServletResponse response) {fileService.download1(request, response);}public void download1(HttpServletRequest request, HttpServletResponse response) {String path = request.getParameter("path");response.setCharacterEncoding("utf-8");InputStream inputStream = null;File file = null;BufferedOutputStream bw = null;try {file = new File(filePath + path);log.warn("开始下载文件: " + filePath + path);System.out.println("开始下载文件: " + filePath + path);// 分片下载long fSize = file.length();// 应中文可能会出翔的乱码String fileName = URLEncoder.encode(file.getName(), utf8);response.setContentType("application/x-download");// 让用户选择下载到的地址response.addHeader("Content-Disposition", "attachment;filename=" + fileName);// 查看客户端是否支持分片下载response.addHeader("Accept-Ranges", "bytes");response.addHeader("fSize", String.valueOf(fSize));response.addHeader("fName", "IDEA.zip");long pos = 0, last = fSize - 1, sum = 0;long rangeLength = last - pos + 1;String contentRange = new StringBuffer("bytes ").append(pos).append("-").append(last).append("/").append(fSize).toString();response.setHeader("Content-Range", contentRange);response.setHeader("Content-Length", String.valueOf(rangeLength));bw = new BufferedOutputStream(response.getOutputStream());inputStream = new BufferedInputStream(new FileInputStream(file));byte[] bytes = new byte[1024];int temp = 0;while (sum < rangeLength) {temp = inputStream.read(bytes);sum += temp;bw.write(bytes, 0, temp);bw.flush();}log.warn("下载完成");System.out.println("下载完成");} catch (IOException e) {e.printStackTrace();} finally {try {if (inputStream != null) {inputStream.close();}if (bw != null) {bw.close();}} catch (IOException e) {e.printStackTrace();}}}

后端获取文件列表和创建文件,删除文件

@RequestMapping("/getFilePath")@ResponseBody@CrossOriginpublic ApiResponse getFilePath(HttpServletRequest request, HttpServletResponse response) {HashMap<String, Object> filePath = fileService.getFilePath(request, response);return ApiResponse.OK(filePath);}@RequestMapping("/createFile")@ResponseBody@CrossOriginpublic ApiResponse createFile(HttpServletRequest request, HttpServletResponse response) {return fileService.createFile(request, response);}@RequestMapping("/deleteFile")@ResponseBody@CrossOriginpublic ApiResponse deleteFile(HttpServletRequest request, HttpServletResponse response) throws InterruptedException, UnsupportedEncodingException {return fileService.deleteFile(request, response);}

项目到此顺利完成.

web uploader实现文件的上传和下载功能相关推荐

  1. java上传与下载文件_java实现文件的上传和下载功能

    准备工作 (视频教程推荐:java课程) 需要导入的jar包 运行截图 文件上传截图 文件下载截图 上传文件代码servlet@WebServlet(name = "UploadServle ...

  2. SpringMVC实现文件的上传和下载

    SpringMVC实现文件的上传和下载http://www.bieryun.com/1120.html 前些天一位江苏经贸的学弟跟我留言问了我这样一个问题:"用什么技术来实现一般网页上文件的 ...

  3. nginx java文件上传_Nginx实现文件的上传和下载

    文件的上传只要保证特殊的地址先到达Nginx,然后通过Nginx指定至指定的服务器即可,目前配置是本机.文件的下载的做法就是把本机的当前目录下面的文件给返回回去. server { listen ; ...

  4. SpringBoot+Vue3实现文件的上传和下载

    目录 前言 上传前端页面 上传后端代码 下载后端代码 下载前端代码 总结 参考文献 前言 上传文件和下载文件是我们平时经常用到的功能,接下来就让我们用SpringBoot,Vue3和ElementPl ...

  5. 初学Java Web(7)——文件的上传和下载

    文件上传 文件上传前的准备 在表单中必须有一个上传的控件 <input type="file" name="testImg"/> 因为 GET 方式 ...

  6. Akka实战:HTTP大文件断点上传、下载,秒传

    2019独角兽企业重金招聘Python工程师标准>>> 访问:https://github.com/yangbajing/scala-applications/tree/master ...

  7. SpringMVC实现文件的上传与下载

    文件的上传与下载可以说是工作中经常使用的功能,现在整理一下,希望能够给大家一个参考.这里以 Maven 的形式来创建项目,相关的配置文件会把主要的内容列出来,其他头文件信息不再一一全部的列出.最后会把 ...

  8. 文件的上传和下载---学习笔记

    文件上传原理 在TCP/IP中,最早出现的文件上传机制是FTP.它是将文件由客户端发送到服务器的标准机制. 但是JSP编程中不能使用FTP方法来上传文件,这是由JSP运行机制所决定的. JSP中上传文 ...

  9. SpringMVC与JSON传值,取值,使用SpringMVC实现文件的上传与下载,SpringMVC拦截器

    一. JSON 1.1 什么是JSON 在实际开发中,通常需要和别的系统交换数据,数据交换的格式通常有XML和JSON等: JSON(JavaScript Object Notation:JavaSc ...

最新文章

  1. oracle给换服务器,Oracle数据库更换服务器10分钟切换方案
  2. 牛客题霸 SQL4 查找所有已经分配部门的员工的last_name和first_name以及dept_no
  3. servlet的几个函数
  4. 成为最大的独立开源公司,对SUSE意味着什么? | 人物志
  5. 【报告分享】2020海外留学趋势报告.pdf(附下载链接)
  6. 25 岁的 JavaScript 都经历了什么?
  7. 项目管理笔记(观念)
  8. 阿里云云计算 41 阿里云CDN的工作原理
  9. WebGL白模做专题图注意事项
  10. mysql数据库约束和默认
  11. 大牛直播sdk简单播放端demo使用
  12. 硬件设计——PWM原理与设计
  13. android qq语音按钮,qq语音设置怎么操作?手机qq语音设置在哪里
  14. C语言time.h中srand(),rand()等等函数产生随机数的用法。
  15. 东原服务器开机显示bb,启用tls后,服务器出现remote error: tls: bad certificate
  16. 【BZOJ1062】糖果雨(NOI2008)-数形结合+二维树状数组
  17. vue axios常用写法
  18. Html-小米官网头部
  19. 数组传参的三种方法:泛型;压扁数组;数组结构
  20. python挖掘B站猛男手游公主连结的另类操作!

热门文章

  1. 【Python游戏】基于化学方程式的基础上,用Python实现一个消灭泡泡小游戏 | 附源码
  2. 2.5 TCP网络协议
  3. 微软服务器安全补丁,明明白白打补丁,微软12月安全公告摘要详解
  4. 谷歌、亚马逊、IBM和微软的云计算平台
  5. STM32下推式磁悬浮装置(三)PID调试与源码分析
  6. ADIS16465姿态解算+卡尔曼滤波代码
  7. 第03课:生活中的状态模式——人与水的三态
  8. mt6572 flash tool 下载报错
  9. 各种开关的教程---凯利讯半导体
  10. 小灰灰的APP学习之路(一)--开发工具安装