Plupload 是一个Web浏览器上的界面友好的文件上传模块,可显示上传进度、图像自动缩略和上传分块。可同时上传多个文件;

  上网找了很多Plupload的DEMO都无法正常使用, 而且Plupload官方的DEMO是基于PHP, 折腾了半天, 写了一个基于JAVA的DEMO;

  Plupload支持多种方式上传, 包括,flash上传(解决了不同服务器跨域的问题), html5方式上传, html4上传, silverlight的方式上传, Plupload的核心是另外一个JS库:

    MOXIE, MOXIE提供了Plupload的运行环境, 也可以单独拿出来使用, 代码量(体积)挺大的,MOXIE提供了下面几种上传环境:  

      

  Plupload支持分块上传, 支持拖拽上传, 支持图片切块, 支持30多种语言, 而且提供了丰富的API, 因为支持多种方式上传, 可以比较放心的使用这个JS插件;

  容器是tomcat, 需要java的spring框架, 需要apache的几个jar包, commons.fileupload等....;

  以下代码是处理文件上传的java代码:

运行下面代码

package controller;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.UUID; import javax.servlet.ServletConfig;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody; import com.alibaba.fastjson.JSON; @Controller
public class mainController { String uploadPath;
private static final ResourceBundle bundle = ResourceBundle.getBundle( "config" ); @RequestMapping(value="uploadFile.do", method=RequestMethod.POST)
public void uploadFile( HttpServletRequest request, HttpServletResponse response ) throws IOException { response.setCharacterEncoding( "UTF-8" );
Integer chunk = null; /* 分割块数 */
Integer chunks = null; /* 总分割数 */
String tempFileName = null; /* 临时文件名 */
String newFileName = null; /* 最后合并后的新文件名 */
BufferedOutputStream outputStream = null; /* System.out.println(FileUtils.getTempDirectoryPath()); */
uploadPath = request.getServletContext().getRealPath( bundle.getString( "uploadPath" ) );
File up = new File( uploadPath );
if ( !up.exists() )
{
up.mkdir();
} if ( ServletFileUpload.isMultipartContent( request ) )
{
try {
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold( 1024 );
/* factory.setRepository(new File(repositoryPath));// 设置临时目录 */
ServletFileUpload upload = new ServletFileUpload( factory );
upload.setHeaderEncoding( "UTF-8" );
/* upload.setSizeMax(5 * 1024 * 1024);// 设置附件最大大小,超过这个大小上传会不成功 */
List<FileItem> items = upload.parseRequest( request );
for ( FileItem item : items )
{
if ( item.isFormField() ) /* 是文本域 */
{
if ( item.getFieldName().equals( "name" ) )
{
tempFileName = item.getString();
/* System.out.println("临时文件名:" + tempFileName); */
} else if ( item.getFieldName().equals( "chunk" ) )
{
chunk = Integer.parseInt( item.getString() );
/* System.out.println("当前文件块:" + (chunk + 1)); */
} else if ( item.getFieldName().equals( "chunks" ) )
{
chunks = Integer.parseInt( item.getString() );
/* System.out.println("文件总分块:" + chunks); */
}
} else { /* 如果是文件类型 */
if ( tempFileName != null )
{
String chunkName = tempFileName;
if ( chunk != null )
{
chunkName = chunk + "_" + tempFileName;
}
File savedFile = new File( uploadPath, chunkName );
item.write( savedFile );
}
}
} newFileName = UUID.randomUUID().toString().replace( "-", "" )
.concat( "." )
.concat( FilenameUtils.getExtension( tempFileName ) );
if ( chunk != null && chunk + 1 == chunks )
{
outputStream = new BufferedOutputStream(
new FileOutputStream( new File( uploadPath, newFileName ) ) );
/* 遍历文件合并 */
for ( int i = 0; i < chunks; i++ )
{
File tempFile = new File( uploadPath, i + "_" + tempFileName );
byte[] bytes = FileUtils.readFileToByteArray( tempFile );
outputStream.write( bytes );
outputStream.flush();
tempFile.delete();
}
outputStream.flush();
}
Map<String, Object> m = new HashMap<String, Object>();
m.put( "status", true );
m.put( "fileUrl", bundle.getString( "uploadPath" ) + "/"
+ newFileName );
response.getWriter().write( JSON.toJSONString( m ) );
} catch ( FileUploadException e ) {
e.printStackTrace();
Map<String, Object> m = new HashMap<String, Object>();
m.put( "status", false );
response.getWriter().write( JSON.toJSONString( m ) );
} catch ( Exception e ) {
e.printStackTrace();
Map<String, Object> m = new HashMap<String, Object>();
m.put( "status", false );
response.getWriter().write( JSON.toJSONString( m ) );
} finally {
try {
if ( outputStream != null )
outputStream.close();
} catch ( IOException e ) {
e.printStackTrace();
}
}
}
} public void main() { } }

  

  前端界面的主要代码:

运行下面代码

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>plupload示例</title>
<script src="http://cdn.bootcss.com/jquery/1.9.0/jquery.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/plupload.full.min.js"></script> </head>
<body>
<div id="filelist"> </div>
<button id="uploader">选择文件</button>
<div id="progress"></div>
<div id="result"></div>
</body>
<script type="text/javascript">
var uploader = new plupload.Uploader({
runtimes : 'html5,flash,silverlight',//设置运行环境,会按设置的顺序,可以选择的值有html5,gears,flash,silverlight,browserplus,html
flash_swf_url : './js/Moxie.swf',
silverlight_xap_url : './js/Moxie.xap',
url : '${pageContext.request.contextPath}/uploadFile.do',//上传文件路径
max_file_size : '3gb',//100b, 10kb, 10mb, 1gb
chunk_size : '1mb',//分块大小,小于这个大小的不分块
unique_names : true,//生成唯一文件名
browse_button : 'uploader',
filters : [ {
title : 'Image files',
extensions : 'jpg,gif,png'
}, {
title : 'Zip files',
extensions : 'zip,7z,rar'
} ], init : {
FilesAdded: function(up, files) { uploader.start();
return false;
},
FileUploaded : function(up, file, info) {//文件上传完毕触发
console.log("单独文件上传完毕");
var response = $.parseJSON(info.response);
if (response.status) {
$('#result').append( $('<div> "文件路径是:"' + response.fileUrl + '"随机的文件名字为:"' + file.name + '</div>') );
}
},
UploadComplete : function( uploader,files ) {
console.log("所有文件上传完毕");
},
UploadProgress : function( uploader,file ) {
$("#progress").html("上传进度为:" + file.percent + "%");
console.log( file.percent );
}
}
}); uploader.init();
</script>
</html>

  

  整体界面如下:

  

  整体代码放在baidu云盘: 打开下载

  github项目

  plupload中文文档

  百度网盘链接

天道酬勤

Plupload上传组件 + javaweb实现上传源码以及DEMO的更多相关文章

  1. 如何优雅的阅读 GitHub 上开源 js 框架和库的源码

    如何优雅的阅读 GitHub 上开源 js 框架和库的源码 step 先总后分,即先了解一下啊框架的大体架构,又一个全局的认识,在选择某些和感兴趣的部分,仔细阅读,各个击破: 带着问题阅读,用到了什么 ...

  2. php文件上传原理详解(含源码)

    1.文件上传原理 将客户端的文件上传到服务器,再将服务器的临时文件上传到指定目录 2.客户端配置 提交表单 表单的发送方式为post 添加enctype="multipart/form-da ...

  3. SpringMVC+BUI实现文件上传(附详解,源码下载)

    中午有限时间写这博文,前言就不必多说了,直奔主题吧. BUI是一个前端框架,关于BUI的介绍请看博主的文章那些年用过的一些前端框架. 下面我们开始实例的讲解! 一.效果演示: 上传成功后,会发现本地相 ...

  4. 微信小程序多图上传/朋友圈传图效果【附完整源码】

    效果图 部分源代码 js文件: var uploadPicture = require('../Frameworks/common.js') //获取应用实例 const app = getApp() ...

  5. v79.01 鸿蒙内核源码分析(用户态锁篇) | 如何使用快锁Futex(上) | 百篇博客分析OpenHarmony源码

    百篇博客分析|本篇为:(用户态锁篇) | 如何使用快锁Futex(上) 进程通讯相关篇为: v26.08 鸿蒙内核源码分析(自旋锁) | 当立贞节牌坊的好同志 v27.05 鸿蒙内核源码分析(互斥锁) ...

  6. 在centos7上安装gcc、node.js(源码下载)

    一.在centos7中安装node.js https://www.cnblogs.com/lpbottle/p/7733397.html 1.从源码下载Nodejs cd /usr/local/src ...

  7. Windows上IDEA搭建最新Spark2.4.3源码调试的开发环境

    相信很多同学都想通过阅读一些框架的源码,来提高自己的代码能力,但往往在第一步,搭建环境的时候就碰了壁. 本篇就来介绍下如何在Windows下,将最新版的Spark2.4.3编译,并导入到IDEA编译器 ...

  8. GitHub 上值得参考的完整的 iOS-App 源码

    转自:https://www.zhihu.com/question/28518265 作者:wjh2005链接:https://www.zhihu.com/question/28518265/answ ...

  9. 史上最详细的Android消息机制源码解析

    本人只是Android菜鸡一个,写技术文章只是为了总结自己最近学习到的知识,从来不敢为人师,如果里面有不正确的地方请大家尽情指出,谢谢! 606页Android最新面试题含答案,有兴趣可以点击获取. ...

随机推荐

  1. DuiLib 源码分析之解析xml类CMarkup & CMarkupNode cpp文件

    时隔5个月才有时间接着写未完成的实现部分,也是惭愧呀 选几个关机的函数来解析,一些get方法就忽略掉吧 CMarkupNode 与 CMarkUp 互为友元类,CMarkUp 实现解析,CMarkup ...

  2. localhost访问错误Forbidden You don't have permission to access / on this server.解决办法(亲测)

    在httpd.conf文件下找到这段: <Directory /> Options FollowSymLinks AllowOverride None Order deny,allow D ...

  3. 如何挂自己的web项目(免费拥有自己的网站及域名)

    http://www.blogjava.net/qingshow/archive/2010/01/17/309846.html ------------------------------------ ...

  4. ssh启动报错:org.dom4j.DocumentException: Connection timed out: connect Nested exception: Connection timed out: connect

    ssh项目启动报错: org.dom4j.DocumentException: Connection timed out: connect Nested exception: Connection t ...

  5. IOI2011ricehub米仓

    Description 乡间有一条笔直而长的路称为"米道".沿着这条米道上 R 块稻田,每块稻田的坐标均为一个 1 到 L 之间(含 1 和 L)的整数.这些稻田按照坐标以不减的顺 ...

  6. ExtJS自制表格Grid分页条

    试过Grid自带的load和分页功能,没有成功,干脆就自己写了...... 主要是查询条件比较复杂...... 希望哪位大神能有更好的意见. Ext.define('MyApp.ux.Paginati ...

  7. How threads differ from processes

    How threads differ from processes Threads differ from traditional multitasking operating system proc ...

  8. D​e​p​l​o​y​m​e​n​t​ ​f​a​i​l​u​r​e​ ​o​n​ ​T​o​m​c​a​t​ ​6​.​x​.​ ​C​o​u​l​d​ ​n​o​t​ ​c​o​p​y​ ​a​l​l​ ​r​e​s​o​u​r​c​e​s​ ​t​o

    在myeclipse总部署项目,一直有问题,提示如下的错误,经过研究在网上需求帮助,解决方案如下: Deployment failure on Tomcat  6.x. Could not copy  ...

  9. kaggle数据挖掘竞赛初步--Titanic<原始数据分析&缺失值处理>

    Titanic是kaggle上的一道just for fun的题,没有奖金,但是数据整洁,拿来练手最好不过啦. 这道题给的数据是泰坦尼克号上的乘客的信息,预测乘客是否幸存.这是个二元分类的机器学习问题 ...

  10. Redis常用命令入门3:列表类型

    列表类型 列表类型也是一个我们很长要用到的一个类型.比如我们发博客,要用到博客列表.如果没有列表我们就只能遍历键来获取所有文章或一部分文章了,这个语法是keys,但是这个命令需要遍历数据库中的所有键, ...