Java Web实现文件下载的几种方式

365bet怎么提现 时间: 2025-07-26 05:35:30 作者: admin 查阅次数: 4603 公众评价: 752
Java Web实现文件下载的几种方式

文件下载可以说是网站的基础功能,要实现最下载功能,有一种最基本的方法,那就是将超链接的href属性指向对应的资源文件。

如下面连接指向了百度首页的图片:

I'm the index of Baidu

但这种方式的缺陷也是很明显的,目录信息被获取,不利于信息安全。其实信息安全还是其次,主要还是因为它不方便。如果直接指向资源文件,那么浏览器会自动打开图片等一些文件,而不会弹出窗口提示用户保存。

因此这种方式并不能很好地解决下载的问题。因此就有了下面的几种下载方式。

而在Java中,要实现下载功能一般有三种实现方式:

1、使用Servlet实现文件下载

2、在Struts中用Servlet实现下载

3、使用Struts框架提供的文件下载功能

其实这三种实现方式的原理都一样,都是利用InputStream从文件中读取数据,然后利用OutputStream将数据接入到返回客户端的response中。

其核心代码如下:

代码语言:javascript代码运行次数:0运行复制 1 try {

2 InputStream inStream = new FileInputStream(file);

3 ServletOutputStream servletOS = response.getOutputStream();

4 byte[] buf = new byte[4096];

5 int readLength;

6 while((readLength = inStream.read(buf))!= -1)

7 {

8 servletOS.write(buf, 0, readLength);

9 }

10 inStream.close();

11 servletOS.flush();

12 servletOS.close();

13 }

14 catch(Exception e)

15 {

16 e.printStackTrace();

17 }

18 return response;其中第一种在Servlet中实现文件下载是最原始的下载方式。而第二种在Struts中用Servlet实现文件下载也是最原始的方式,只不过我们是在Struts的Action中进行操作,不用去创建Servlet。

而第三种则是Struts对文件下载功能进行了封装,我们只要按照其规定的配置就可以直接使用。

这几种方式各有各的优缺点,选择适合自己的方式即可。下面对上面提到的三种方式进行详细解析:

一、使用Servlet实现文件下载

这种方式性能最好,条理最清晰,但是可能代码量多了点。

准备:只需Java的JDK即可运行。

1、在web.xml中进行Servlet配置

代码语言:javascript代码运行次数:0运行复制 1

2

3 xmlns="http://java.sun.com/xml/ns/javaee"

4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

5 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

6 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

7

8

9

10 fileDownLoadServlet

11 com.chanshuyi.download.FileDownLoadServlet

12

13

14 fileDownLoadServlet

15 /fileDownLoadServlet

16

17 2、创建Servlet类

代码语言:javascript代码运行次数:0运行复制 1 package com.chanshuyi.download;

2

3 import java.io.File;

4 import java.io.FileInputStream;

5 import java.io.IOException;

6 import java.io.InputStream;

7 import java.io.UnsupportedEncodingException;

8 import java.net.URLEncoder;

9

10 import javax.servlet.ServletException;

11 import javax.servlet.ServletOutputStream;

12 import javax.servlet.http.HttpServlet;

13 import javax.servlet.http.HttpServletRequest;

14 import javax.servlet.http.HttpServletResponse;

15

16 /**

17 * 文件下载Servlet

18 * @param filePath 下载文件相对于项目根目录的相对地址

如:uploaded\hello.txt

19 * @author chenyr

20 *

21 */

22 @SuppressWarnings("serial")

23 public class FileDownLoadServlet extends HttpServlet {

24

25 /** 项目的根目录

如:D:\Workspaces\DownUpProject\WebRoot\ **/

26 private String rootPath;

27

28 /** 下载文件的相对于项目根目录的相对路径 **/

29 private String filePath;

30

31 /** 下载文件在磁盘的绝对路径 **/

32 private String fullPath;

33

34 /** 下载文件名 **/

35 private String fileName;

36

37 /** 编码过后的下载文件名 **/

38 private String encodeFileName;

39

40 /**

41 * 自定义init,用于初始化下载所属属性

42 * @param request

43 * @return

44 * @throws UnsupportedEncodingException

45 */

46 public boolean myInit(HttpServletRequest request)

47 {

48 boolean flag = false;

49 try

50 {

51 setRootPath(this.getServletContext().getRealPath("/"));

52 setFilePath(new String(request.getParameter("filePath").getBytes("iso-8859-1"), "utf-8"));

53 setFullPath(getRootPath() + getFilePath());

54

55 setFileName(getFilePath().substring(getFilePath().lastIndexOf("\\") + 1));

56 setEncodeFileName(URLEncoder.encode(getFileName(), "utf-8")); //支持中文文件名

57

58 flag = true;

59 }

60 catch(Exception e)

61 {

62 e.printStackTrace();

63 }

64 return flag;

65 }

66

67 /**

68 * Servlet类的服务方法

69 */

70 @Override

71 protected void service(HttpServletRequest request,

72 HttpServletResponse response) throws ServletException, IOException {

73 download(request, response);

74 }

75

76 /**

77 * 文件下载

78 * @param path

79 * @param request

80 * @param response

81 * @return

82 * @throws UnsupportedEncodingException

83 */

84 public HttpServletResponse download(HttpServletRequest request, HttpServletResponse response){

85 /* 初始化相关属性信息 */

86 myInit(request);

87

88 /* 检查文件是否存在 */

89 File file = new File(getFullPath());

90 if(!file.exists())

91 {

92 System.out.println("文件不存在:" + file.getAbsolutePath());

93 return null;

94 }

95

96 /* 设置response头信息 */

97 response.reset();

98 response.setContentType("application/octet-stream"); //代表任意二进制数据

99 response.addHeader("Content-Disposition", "attachment;filename=\"" + getEncodeFileName() + "\"");

100 response.setContentLength((int)file.length());

101

102 /* 读取文件数据流 */

103 if(file.exists())

104 {

105 /* 读取文件数据 */

106 if((int)file.length() != 0)

107 {

108 try

109 {

110 InputStream inStream = new FileInputStream(file);

111

112 ServletOutputStream servletOS = response.getOutputStream();

113 byte[] buf = new byte[4096];

114 int readLength;

115 while((readLength = inStream.read(buf))!= -1)

116 {

117 servletOS.write(buf, 0, readLength);

118 }

119

120 inStream.close();

121 servletOS.flush();

122 servletOS.close();

123 }

124 catch(Exception e)

125 {

126 e.printStackTrace();

127 }

128 }

129 }

130 return response;

131 }

132

133 /*

134 * GET/SET

135 */

136 public String getFilePath() {

137 return filePath;

138 }

139

140 public void setFilePath(String filePath) {

141 this.filePath = filePath;

142 }

143

144 public String getFullPath() {

145 return fullPath;

146 }

147

148 public void setFullPath(String fullPath) {

149 this.fullPath = fullPath;

150 }

151

152 public String getFileName() {

153 return fileName;

154 }

155

156 public void setFileName(String fileName) {

157 this.fileName = fileName;

158 }

159

160 public String getEncodeFileName() {

161 return encodeFileName;

162 }

163

164 public void setEncodeFileName(String encodeFileName) {

165 this.encodeFileName = encodeFileName;

166 }

167

168 public String getRootPath() {

169 return rootPath;

170 }

171

172 public void setRootPath(String rootPath) {

173 this.rootPath = rootPath;

174 }

175 }这个Servlet类对下载功能进行很好的封装,只需要传入名字为:filePath的参数就可以进行下载(filePath是下载文件相对于根目录[WEBROOT目录]的相对路径)。

98行设置response的contentType为application/octet-stream,可以实现任意类型文件的下载。

56行设置URLEncoder.encode对文件名进行编码转换,实现对中文文件名的下载支持。

3、创建访问页面测试

代码语言:javascript代码运行次数:0运行复制 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

2 <%

3 String path = request.getContextPath();

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

5 %>

6

7

8

9

10

11

12 My JSP 'index.jsp' starting page

13

14

15

16

17

18

21

22

23

24 哈哈,测试文件下载

25

26 二、在Struts中用Servlet实现下载

这种方式其实就是将数据流写入response中,其实现方式与第一种完全相同。不同的是在Servlet类中,我们可以直接得到request、response、ServletContext,但是在Struts的Action中我们必须通过其他方式得到这几个变量。

下面的代码实在第一种实现方式的代码的基础上进行少量修改而成的,它实现了在Struts Action中下载的功能:

代码语言:javascript代码运行次数:0运行复制package com.chanshuyi.download;

import java.io.File;

import java.io.FileInputStream;

import java.io.InputStream;

import java.io.UnsupportedEncodingException;

import java.net.URLEncoder;

import javax.servlet.ServletContext;

import javax.servlet.ServletOutputStream;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

@SuppressWarnings("serial")

public class FileDownloadViaServlet extends ActionSupport {

HttpServletRequest request = ServletActionContext.getRequest();

HttpServletResponse response = ServletActionContext.getResponse();

ServletContext servletContext = ServletActionContext.getServletContext();

/** 项目的根目录

如:D:\Workspaces\DownUpProject\WebRoot\ **/

private String rootPath;

/** 下载文件的相对于项目根目录的相对路径 **/

private String filePath;

/** 下载文件在磁盘的绝对路径 **/

private String fullPath;

/** 下载文件名 **/

private String fileName;

/** 编码过后的下载文件名 **/

private String encodeFileName;

/**

* 自定义init,用于初始化下载所属属性

* @param request

* @return

* @throws UnsupportedEncodingException

*/

public boolean myInit()

{

boolean flag = false;

try

{

setRootPath(servletContext.getRealPath("/"));

setFilePath(new String(request.getParameter("filePath").getBytes("iso-8859-1"), "utf-8"));

setFullPath(getRootPath() + getFilePath());

setFileName(getFilePath().substring(getFilePath().lastIndexOf("\\") + 1));

setEncodeFileName(URLEncoder.encode(getFileName(), "utf-8")); //支持中文文件名

flag = true;

}

catch(Exception e)

{

e.printStackTrace();

}

return flag;

}

/**

* Action执行方法

*/

@Override

public String execute() {

download();

return null;

}

/**

* 文件下载

* @param path

* @param request

* @param response

* @return

* @throws UnsupportedEncodingException

*/

public HttpServletResponse download(){

/* 初始化相关属性信息 */

myInit();

/* 检查文件是否存在 */

File file = new File(getFullPath());

if(!file.exists())

{

System.out.println("文件不存在:" + file.getAbsolutePath());

return null;

}

/* 设置response头信息 */

response.reset();

response.setContentType("application/octet-stream"); //代表任意二进制数据

response.addHeader("Content-Disposition", "attachment;filename=\"" + getEncodeFileName() + "\"");

response.setContentLength((int)file.length());

/* 读取文件数据流 */

if(file.exists())

{

/* 读取文件数据 */

if((int)file.length() != 0)

{

try

{

InputStream inStream = new FileInputStream(file);

ServletOutputStream servletOS = response.getOutputStream();

byte[] buf = new byte[4096];

int readLength;

while((readLength = inStream.read(buf))!= -1)

{

servletOS.write(buf, 0, readLength);

}

inStream.close();

servletOS.flush();

servletOS.close();

}

catch(Exception e)

{

e.printStackTrace();

}

}

}

return response;

}

/*

* GET/SET

*/

public String getFilePath() {

return filePath;

}

public void setFilePath(String filePath) {

this.filePath = filePath;

}

public String getFullPath() {

return fullPath;

}

public void setFullPath(String fullPath) {

this.fullPath = fullPath;

}

public String getFileName() {

return fileName;

}

public void setFileName(String fileName) {

this.fileName = fileName;

}

public String getEncodeFileName() {

return encodeFileName;

}

public void setEncodeFileName(String encodeFileName) {

this.encodeFileName = encodeFileName;

}

public String getRootPath() {

return rootPath;

}

public void setRootPath(String rootPath) {

this.rootPath = rootPath;

}

}三、使用Struts框架提供的文件下载功能

通过Struts封装的方式实现文件下载,我们需要在Struts配置文件中进行Response HTTP头等信息的设置,以及建立对应的Action。

准备:导入Struts所需的Jar包,并搭建好Struts环境。不清楚的,可以点这里:Struts框架配置详解

1、在Struts中添加Action

代码语言:javascript代码运行次数:0运行复制 1

2

3

4 佛山“狠刹”四风网络监督平台短信责任人填报表V1.0.xls

5

6 application/vnd.ms-excel

7 mbInputStream

8 attachment;filename=${downloadFileName}

9 4096

10

11 其中mbInputStream中的mbInputStream对应Action中类型为InputStream的属性。

2、创建Action类

代码语言:javascript代码运行次数:0运行复制 1 package com.chanshuyi.download;

2

3 import java.io.FileNotFoundException;

4 import java.io.InputStream;

5 import java.io.UnsupportedEncodingException;

6 import java.net.URLEncoder;

7

8 import javax.servlet.http.HttpServletRequest;

9

10 import org.apache.struts2.ServletActionContext;

11

12 import com.opensymphony.xwork2.ActionSupport;

13

14 public class FileDownLoadAction extends ActionSupport {

15

16 /** 项目的根目录

如:D:\Workspaces\DownUpProject\WebRoot\ **/

17 private String rootPath;

18

19 /** 下载文件的相对于项目根目录的相对路径 **/

20 private String filePath;

21

22 /** 下载文件在磁盘的绝对路径 **/

23 private String fullPath;

24

25 /** 下载文件名 **/

26 private String fileName;

27

28 /** 编码过后的下载文件名 **/

29 private String encodeFileName;

30

31

32 /** 对应于配置文件的输入流 **/

33 private InputStream inputStream;

34

35 public String getRootPath() {

36 return rootPath;

37 }

38

39 public void setRootPath(String rootPath) {

40 this.rootPath = rootPath;

41 }

42

43 public String getFilePath() {

44 return filePath;

45 }

46

47 public void setFilePath(String filePath) {

48 this.filePath = filePath;

49 }

50

51 public String getFullPath() {

52 return fullPath;

53 }

54

55 public void setFullPath(String fullPath) {

56 this.fullPath = fullPath;

57 }

58

59 public String getFileName() {

60 return fileName;

61 }

62

63 public void setFileName(String fileName) {

64 this.fileName = fileName;

65 }

66

67 public void setEncodeFileName(String encodeFileName) {

68 this.encodeFileName = encodeFileName;

69 }

70

71 /**

72 * 初始化参数

73 * @throws UnsupportedEncodingException

74 */

75 public void myInit() throws UnsupportedEncodingException

76 {

77 HttpServletRequest request = ServletActionContext.getRequest();

78

79 setRootPath(ServletActionContext.getServletContext().getRealPath("/"));

80 setFilePath(new String(request.getParameter("filePath").getBytes("iso-8859-1"), "utf-8"));

81 setFullPath(getRootPath() + getFilePath());

82

83 setFileName(getFilePath().substring(getFilePath().lastIndexOf("\\") + 1));

84 setEncodeFileName(URLEncoder.encode(getFileName(), "utf-8")); //支持中文文件名

85 }

86

87 /**

88 * 对应的Action方法

89 * @return

90 * @throws UnsupportedEncodingException

91 */

92 public String download() throws UnsupportedEncodingException

93 {

94 myInit();

95 return SUCCESS;

96 }

97

98 /**

99 * 对文件名进行编码转换,以支持中文文件名

100 * @return

101 */

102 public String getEncodeFileName() {

103 return encodeFileName;

104 }

105

106 /**

107 * 获取下载文件的输入流

108 * @return

109 * @throws FileNotFoundException

110 */

111 public InputStream getInputStream() throws FileNotFoundException {

112 return new java.io.FileInputStream(getFullPath());

113 }

114 }

关联

computer 的意思和词源
microsoft 365下载

computer 的意思和词源

📅 07-08 👁️ 7099
晨字的五行属性及含义(五行属土最旺的字男孩)
365bet娱乐场注册

晨字的五行属性及含义(五行属土最旺的字男孩)

📅 06-28 👁️ 6280
东亚杯名单公布:中国队总身价排名第三
365bet怎么提现

东亚杯名单公布:中国队总身价排名第三

📅 07-15 👁️ 5882

链接