声明
本文部分内容参考自其他作者原创文章,仅供个人学习留档,特此声明
HttpServletResponse简单应用之文件下载
这一节的核心在于header设置某key为 attachment;filename=
即设置想办法让浏览器能够支持(Content-Disposition)下载我们需要的东西,中文文件名URLEncoder.encode编码,否则有可能乱码
resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
1.首先思考一下下载文件需要经历哪些步骤?
要获取下载文件的路径
要下载文件的文件名是什么?
想办法让浏览器能够支持下载我们想要的文件(设置)
获取下载文件的输入流
创建缓冲区;获取OutputStream对象;将FileOutputStream流写入到buffer缓冲区
使用OutputStream将缓冲区中的数据输出到客户端!
2.接下来写程序,将用于下载的图片文件放到资源文件夹下
1、代码
1.用于下载文件的FileServlet代码
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 获取下载文件的路径
String realPath = "E:\\environment\\Maven\\MavenStudy\\javaweb-002-servlet\\response\\target\\classes\\1.png";
System.out.println("下载文件的路径:" + realPath);
// 2. 下载的文件名是什么?
String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
// 3. 设置想办法让浏览器能够支持(Content-Disposition)下载我们需要的东西,中文文件名URLEncoder.encode编码,否则有可能乱码
resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
// 4. 获取下载文件的输入流
FileInputStream in = new FileInputStream(realPath);
// 5. 创建缓冲区
int len = 0;
byte[] buffer = new byte[1024];
// 6. 获取OutputStream对象
ServletOutputStream out = resp.getOutputStream();
// 7. 将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端!
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
//8.关闭所有流
in.close();
out.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
2.用于注册映射路径的web.xml代码
<servlet>
<servlet-name>filedown</servlet-name>
<servlet-class>com.xy.servlet.FileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>filedown</servlet-name>
<url-pattern>/down</url-pattern>
</servlet-mapping>
3.用于防止打包内容不全的pom.xml代码
<!--在pom.xml的<build>中配置<resources>,来防止我们资源导出失败的问题-->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.png</include>
</includes>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
2、代码测试
进入测试网页 http://localhost:8080/response/down
之后如下图所示自动下载
打开下载好的文件看一下,下载成功了
3、一些问题(解决)
1.打包的时候不打包.png文件
解决方法依旧是在pom.xml文件里添加resource,如下(以后此类问题都可以这样处理)
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.png</include>
</includes>
</resource>
2.找不到想要下载资源的路径
解决方法是可以把路径写死成文件的绝对路径
解决步骤如下:
- 我们用一个相对简单的方法获得文件的绝对路径
- 找到想要下载的那个文件(打包好的)
- 右击 --> copy path --> absolute path
- 把这个路径复制到FileServlet代码中即可(把路径写死)
// 1. 要获取下载文件的路径
String realPath = "E:\\environment\\Maven\\MavenStudy\\javaweb-002-servlet\\response\\target\\classes\\1.png";
3.如何用一个简单方法获取下载文件名?(以下方法记住即可,常用)
首先我们观察一下要下载的文件的存在路径
//1.要获取下载文件的路径
String realPath = "E:\\environment\\Maven\\MavenStudy\\javaweb-002-servlet\\response\\target\\classes\\1.png";
很明显,下载文件的realPath的最后一个 \ \ 后边的字符串就是下载的文件名
E:\\environment\\Maven\\MavenStudy\\javaweb-002-servlet\\response\\target\\classes\\1.png
最后一个 \ \ 后边的字符串为 1.png
这就是下载文件的文件名
所以我们用下边这行代码来获取下载文件名
//2.下载的文件名是什么?
String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);