java+web+批量下载文件
JavaWeb 文件下载功能
文件下载的实质就是文件拷贝,将文件从服务器端拷贝到浏览器端,所以文件下载需要IO技术将服务器端的文件读取到,然后写到response缓冲区中,然后再下载到个人客户端。
1. 文件名 - 接受前端发来的文件名
获取到前端页面发送过来的要下载的文件的名字
String filenameValue = req.getParameter("filename");
2. ServletContext域 - 获取到ServletContext域对象
后面将调用此对象的一系列方法,用于获取文件路径、文件MimeType,并设置文件输出类型
ServletContext servletContext = req.getServletContext(); //获取到ServletContext域对象
3. 文件路径 - 获取指定文件在web项目中的路径
通过获取到ServletContext域对象的getRealPath()方法,读取download目录下文件的绝对路径
注意:download目录必须放在webContent目录下面,否则可能会找不到,导致报异常,在读取资源的时候,项目demo会直接去查找webContent下面的文件和文件夹
String realPath = servletContext.getRealPath("download/"+filenameValue); //获取到要下载文件在web项目中的绝对路径
4. 文件MimeType - 获取文件的MimeType类型
通过获取到的 ServletContext 域对象的 getMimeType() 方法,获取到文件MimeType
MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的因特网标准。
MIME 协议指示 MIME 用户代理如何显示附加的文件。
MIME 参考手册:http://www.w3school.com.cn/media/media_mimeref.asp
告知浏览器文件的类型:response.setContentType(文件的MIME类型);
String mimeType = servletContext.getMimeType(filenameValue); //获取到要下载文件的mimeType类型
5. 输出类型 - 设置文件的输出类型
根据之前获取到的文件MimeType,然后通过 Response 域对象的 setContentType() 方法,设置文件的输出类型
resp.setContentType(mimeType); //设置文件的输出类型
6. 设置响应头 - 确定文件是内嵌或弹出下载框
通过 Response 域对象的 setHeader("Content-Disposition","attachment;filename="+filename) 方法设置响应头
Content-Disposition(内容处置/处理)
是 MIME 协议的扩展,Content-Disposition 可以控制用户请求所得的内容存为一个文件时提供一个默认的文件名
inline 和 attachment:文件直接在浏览器上显示或者在访问时弹出文件下载对话框。
inline 表示:内嵌显示,文本和图片都可以解析,但对于文件或者视频会自动去调用成attachment,因此可以直接使用inline
attachment:弹出下载框,因为attachment是让文件以附件的形式打开,因此会调用下载,但此下载的功能并没有提示
//设置输出(下载)的文件的默认文件名为filenameValue的值,inline表示内嵌文本和图片,文件和视频会自动调用成attachment
resp.setHeader("Content-Disposition", "inline;filename="+filenameValue);
7. 执行输出(下载) - IO流
7.1 通过 new,创建字节输入流 FileInputStream,读取文件
7.2 通过Response域,创建Servlet的输出流,输出文件
FileInputStream fileInputStream = new FileInputStream(realPath);
ServletOutputStream outputStream = resp.getOutputStream();
int b=0;
byte[] by = new byte[1024*8];
while ((b=fileInputStream.read(by))!=-1) {
outputStream.write(by, 0, b);
}
outputStream.flush();
fileInputStream.close();
outputStream.close(); //关流,response获得流会自动关闭,因此也可以不用手动关
功能实现代码
Java 代码 - /demo/src/com/Download.java
package com;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Download extends HttpServlet{
@Override
public void init(ServletConfig config) throws ServletException {
/**重写了Servlet的init(ServletConfig config)方法后一定要记得调用父类的init方法,
* 否则在service/doGet/doPost方法中使用getServletContext()方法获取ServletContext对象时
* 就会出现java.lang.NullPointerException异常
* */
super.init(config);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/**1. 接受前端页面发送过来的文件名字
* 获取到前端页面发送过来的要下载的文件的名字
* */
String filenameValue = req.getParameter("filename");
//---------------------
// filenameValue = URLEncoder.encode(filenameValue, "gbk");
/**2. 获取到ServletContext域对象
* 后面将调用此对象的一系列方法,用于获取文件路径、文件MimeType、文件输出类型
* */
ServletContext servletContext = req.getServletContext(); //获取到ServletContext域对象
/**3. 获取指定文件在web项目中的路径
* 通过获取到ServletContext域对象的getRealPath()方法,读取download目录下文件的绝对路径
* download目录必须放在webContent目录下面,否则可能会找不到,导致报异常,
* 在读取资源的时候,项目demo会直接去查找webContent下面的文件和文件夹
* */
String realPath = servletContext.getRealPath("download/"+filenameValue); //获取到要下载文件在web项目中的绝对路径
/**4. 获取到文件MimeType
* 通过获取到的ServletContext域对象的getMimeType()方法,获取到文件MimeType
* MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的因特网标准。
* MIME 协议指示 MIME 用户代理如何显示附加的文件。
* MIME 参考手册:http://www.w3school.com.cn/media/media_mimeref.asp
* */
String mimeType = servletContext.getMimeType(filenameValue); //获取到要下载文件的mimeType类型
/**5. 设置文件的输出类型
* Response域对象的setContentType()方法,设置文件的输出类型
* */
resp.setContentType(mimeType); //设置文件的输出类型
/**6. 设置响应头,确定文件是内嵌或弹出下载框
* 通过 Response 域对象的 setHeader("Content-Disposition","attachment;filename="+filename) 方法设置响应头,
* Content-Disposition(内容处置/处理) :
* 是 MIME 协议的扩展,Content-Disposition 可以控制用户请求所得的内容存为一个文件的时候提供一个默认的文件名,
* inline 和 attachment :
* 文件直接在浏览器上显示或者在访问时弹出文件下载对话框。
* inline 表示:内嵌显示,文本和图片都可以解析,但对于文件或者视频会自动去调用成attachment,因此可以直接使用inline
* attachment:弹出下载框
* URLEncoder 对象,将在响应回去的头,里面所代码filename的编码格式,转换为与客户端的一致的编码格式
* URLEncoder.encode(filenameValue,"utf-8"); 将Response响应到浏览器客户端为filenameValue的文件名,转变为utf-8的编码格式
*/
resp.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(filenameValue,"utf-8")); //设置输出(下载)的文件的默认文件名为filenameValue的值,inline表示内嵌文本和图片
/**7. 输出文件(下载文件)
* 7.1 通过 new,创建字节输入流 FileInputStream,读取文件
* 7.2 通过Response域,创建Servlet的输出流,输出文件
* */
FileInputStream fileInputStream = new FileInputStream(realPath);
ServletOutputStream outputStream = resp.getOutputStream();
int b=0;
byte[] by = new byte[1024*8];
while ((b=fileInputStream.read(by))!=-1) {
outputStream.write(by, 0, b);
}
outputStream.flush();
fileInputStream.close();
outputStream.close(); //关流,response获得流会自动关闭,因此也可以不用手动关
}
}
前端页面 jsp 代码 - /demo/WebContent/download.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String path=request.getContextPath();
String basePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html>
<html>
<head>
<!-- <base> 标签为页面上的所有链接规定默认地址或默认目标。 -->
<base href="<%=basePath%>">
<meta charset="UTF-8">
<title>文件下载</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>
<body>
<a href="download?filename=JDBC连接主流数据库.txt">点击下载 文件</a> <br/>
<a href="download?filename=0413102708.avi">点击下载 视频</a>
</body>
</html>
web.xml - /demo/WebContent/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>demo</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<context-param>
<param-name>ServletContextName</param-name>
<param-value>ServletContextValue</param-value>
</context-param>
<servlet>
<servlet-name>Download</servlet-name>
<servlet-class>com.Download</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Download</servlet-name>
<url-pattern>/download</url-pattern>
</servlet-mapping>
</web-app>
下载文件出现中文乱码和不显示文件名的情况
在有些情况下,如果下载中文文件,页面在下载时会出现中文乱码或不能显示文件名的情况,原因是不同的浏览器默认对下载文件的编码方式不同,比如ie是UTF-8编码方式,而火狐浏览器是Base64编码方式。
/**URLEncoder 对象,将在响应回去的头,里面所代码filename的编码格式,转换为与客户端的一致的编码格式
* URLEncoder.encode(filenameValue,"utf-8");
* 将Response响应到浏览器客户端为filenameValue的文件名,转变为utf-8的编码格式
* */
resp.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(filenameValue,"utf-8"));
详细配置信息可以参考这篇文章:http://blog.ncmem.com/wordpress/2019/08/28/java%e6%89%b9%e9%87%8f%e4%b8%8b%e8%bd%bd/
原文地址:https://www.cnblogs.com/songsu/p/11425199.html
- UE4新手编程之创建空白关卡和添加碰撞体
- Office Web Apps
- hadoop: hive 1.2.0 在mac机上的安装与配置
- ASP.NET 5运行时升级到Beta5
- WordPress免插件仅代码实现“返回顶部、返回底部、评论”效果(样式二)
- jQuery/asp.net mvc DateTime 的处理
- WordPress主题下funtions.php的一段“恶意”代码
- eclipse/intellij idea 远程调试hadoop 2.6.0
- Jexus 5.8.2 正式发布为Asp.Net Core进入生产环境提供平台支持
- 区块链技术发展前景可观,银链原子链已开始投入正常交易
- 分布式服务框架 dubbo/dubbox 入门示例
- SmtpClient发送邮件遭遇The specified string is not in the form required for a subject.
- 彻底解决WordPress 中 半角全角字符转义 的问题
- 利用Spring的@Async异步处理改善web应用中耗时操作的用户体验
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 如何用R语言在机器学习中建立集成模型?
- 从零开始Kubernetes Operator
- TiKV源码解析系列文章(二十)Region Split源码解析
- scrapy爬虫框架和selenium的使用:对优惠券推荐网站数据LDA文本挖掘
- 单性状动物模型矩阵形式计算BLUP值
- 如何计算一般配合力和特殊配合力
- 【29期】Java集合框架 10 连问,你有被问过吗?
- 学徒数据挖掘之谁说生存分析一定要按照表达量中位值或者平均值分组呢?
- 软件质量的黄金准则
- 你应该了解的5种TypeScript设计模式
- Vue.js 教程:构建一个特斯拉汽车余电计算器
- 文件系统:隐匿在 Linux 背后的机制
- MySQL在Docker环境下运行基础
- Redis 秒杀实战
- Oracle 19c集群重装步骤详解