Java与WebUploader相结合实现文件上传功能(实例代码)

2025-05-29 0 75

之前自己写小项目的时候也碰到过文件上传的问题,没有找到很好的解决方案。虽然之前网找各种解决方案的时候也看到过WebUploader,但没有进一步深究。这次稍微深入了解了些,这里也做个小结。

简单的文件和普通数据上传并保存

jsp页面:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16
<%@ 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>

servlet:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54
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);

}

}

使用WebUploader组件上传

分片、并发,预览、压缩,多途径添加文件夹(文件多选,拖拽等),妙传

页面样式使用

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25
<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.创建页面元素 -->

<div id="upload">

<div id="filePicker">文件上传</div>

</div>

<!-- 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>

  • 生成文件名列表、实时显示上传进度、显示缩略图
  • 增加文件列表div, <div id="fileList"></div>
  • 生成缩略图和显示上传进度
?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21
// 生成缩略图和上传进度

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

// 把文件信息追加到fileList的div中

$("#fileList").append("<div id='" + file.id + "'><img/><span>" + file.name + "</span><div><span class='percentage'><span></div></div>")

// 制作缩略图

// error:不是图片,则有error

// src:代表生成缩略图的地址

uploader.makeThumb(file, function(error, src) {

if (error) {

$("#" + file.id).find("img").replaceWith("<span>无法预览&nbsp;</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) + "%");

});

  • 拖拽上传、粘贴上传
  • 创建拖拽区域并设置样式:
?

1

2

3

4

5

6

7

8

9

10
<style type="text/css">

#dndArea {

width: 200px;

height: 100px;

border-color: red;

border-style: dashed;

}

</style>

<!-- 创建用于拖拽的区域 -->

<div id="dndArea"></div>

  • 基本配置中增加dnd区域配置(开启拖拽)

屏蔽拖拽区域外的响应

开启粘贴功能

?

1

2

3

4

5

6

7

8

9

10

11

12
var uploader = WebUploader.create(

{ swf:"${pageContext.request.contextPath }/js/Uploader.swf",

server:"${pageContext.request.contextPath }/FileUploadServlet",

pick:"#filePicker",

auto:true,

// 开启拖拽

dnd:"#dndArea",

// 屏蔽拖拽区域外的响应

disableGlobalDnd:true,

//

}

);

  • 文件的分块上传

前端根据需要发送的文件生成一个md5字符串发送给后台,后台创建以该md5字符串命名的文件夹。前端分块发送文件并发送文件块序号给后台,后台接收到文件后按序号名称保存。前端发送完成后通知后台合并文件。

  • 前端配置,开启是否分块、分块大小、线程个数等
?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22
// 上传基本配置

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

}

);

  • 前端监听分块

可以分为三个时间点:

可以在该方法中获取文件的md5字符串作为后台保存分块文件的目录名

  • before-send: 该方法在每个分块文件上传前调用(每个分块上传前都会调用)。

可以在该方法中发送md5字符串到后台,后台判断是否已经存在分块决定是否发送以达到断点续传的功能

  • after-send-file: 该方法在所有文件上传完成没有错误之后调用(所有分块上传完成后调用)。

可以在该方法中通知后台合并所有分块

  • 前端获取文件md5字符串,发送每个分块时发送到后台,后台接收如果不存在文件夹创建文件夹,保存分块发送的文件
?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35
// 监听分块上传的时间点,断点续传

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() {

}

}

);

添加state标签

?

1
$("#fileList").append("<div id='" + file.id + "'><img/><span>" + file.name + "</span><div><span class='state'></span></div><div><span class='percentage'></span></div></div>");

保存文件

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39
// 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);

}

}

  • 前端通知action进行合并文件

前端增加:

?

1

2

3

4

5

6

7

8

9

10

11

12
// 通知合并分块

$.ajax(

{

type:"POST",

url:"${pageContext.request.contextPath}/UploadActionServlet?action=mergeChunks",

data:{

fileMd5:fileMd5

},

success:function(response){

}

}

);

新增合并action:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86
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);

}

}

  • 断点续传

前端页面发送前添加校验,校验是否已经上传分块

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31
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();

}

  • action中添加校验
?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18
else if ("checkChunk".equals(action)) {

// 校验文件是否已经上传并返回结果给前端

// 文件唯一表示

String fileMd5 = request.getParameter("fileMd5");

// 当前分块下标

String chunk = request.getParameter("chunk");

// 当前分块大小

String chunkSize = request.getParameter("chunkSize");

// 找到分块文件

File checkFile = new File(serverPath + "/" + fileMd5 + "/" + chunk);

// 检查文件是否存在,且大小一致

response.setContentType("text/html;charset=utf-8");

if (checkFile.exists() && checkFile.length() == Integer.parseInt((chunkSize))) {

response.getWriter().write("{\\"ifExist\\":1}");

} else {

response.getWriter().write("{\\"ifExist\\":0}");

}

}

以上所述是小编给大家介绍的Java与WebUploader相结合实现文件上传功能(实例代码),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对快网idc网站的支持!

原文链接:http://www.cnblogs.com/liuchengcc/p/6643884.html

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 Java与WebUploader相结合实现文件上传功能(实例代码) https://www.kuaiidc.com/117759.html

相关文章

发表评论
暂无评论