文章目录
ServletContext
-
概念:代表整个web应用的上下文
-
功能
-
获取MIME类型
-
MIME:互联网通信过程中定义的文件数据类型
-
格式:大类型/小类型
比如
text/html
image/jpeg
-
-
获取:
String getMimeType(String file)
-
-
作为域对象,共享数据
- getAttribute(String name,Object value)
- setAttribute(String name,Object value)
- removeAttribute(String name)
ServletContext的作用范围:整个web应用
扫描二维码关注公众号,回复: 12315708 查看本文章 -
获取文件的真实路径(服务器路径)
- String getRealPath(String path)
可用于在程序中加载项目中的某个文件(一般是配置文件)
-
-
获取
-
通过request对象获取
request.getServletContext();
-
通过HttpServlet获取
//在一个HttpServlet类中 this.getServletContext();
-
案例:文件下载
- 页面显示超链接
- 点击超链接后,弹出下载提示框
- 完成文件下载
分析:
- 超链接指向的资源,如果能够被浏览器解析,如图片,则直接会在浏览器中展示,不能被浏览器解析的才会提示下载。所以直接用超链接指向资源文件,不满足需求
- 使用响应头,设置
Content-disposition:attachment;filename=xx
实现步骤:
- 编辑超链接,让其href指向一个servlet,传递资源名称
- 编写Servlet
- 获取文件名称
- 找到对应文件,使用字节输入流加载到内存中
- 指定response的响应头
Content-disposition
- 将数据写到response输出流
代码展示:
html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!-- 浏览器能展示的资源,会直接展示 -->
<a href="/download?filename=达不溜.jpeg">AW</a>
<br>
<!-- 像视频这样,浏览器无法解析
经测试,IE浏览器中,点击此超链接,会提示下载mp4文件
Chrome中,点击超链接,会直接打开mp4文件,在Chrome中直接播放
-->
<a href="/download?filename=my_first_vlog.mp4">vlog</a>
</body>
</html>
其中的资源文件放在了/web/resources目录下
Servlet处理逻辑
@WebServlet("/download")
public class DownloadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext context = getServletContext();
//获取文件,加载到内存中
request.setCharacterEncoding("utf-8");
String filename = request.getParameter("filename");
//给文件名添加路径 /resources ,默认把资源文件都放resources下
filename = "/resources/" + filename;
//获取文件真实路径
String path = context.getRealPath(filename);
FileInputStream inputStream = new FileInputStream(path);
//设置response的响应头,设置content-type和content-disposition
//表明响应体中的数据是什么MIME类型
response.setContentType(context.getMimeType(filename));
//表明以附件形式下载响应体数据
//解决中文文件名问题
// 1. 获取user-agent请求头
// 2. 使用DownloadUtil工具类编码文件名
String userAgent = request.getHeader("user-agent");
filename = DownloadUtil.getFileName(userAgent,filename);
response.setHeader("content-disposition","attachment;filename="+filename);
//输出到response的流
ServletOutputStream outputStream = response.getOutputStream();
byte[] bytes = new byte[1024];
int len = 0;
while ((len = inputStream.read(bytes)) != -1){
outputStream.write(bytes);
}
inputStream.close();
}
}
其中DownloadUtil用于解决不同浏览器对中文文件名支持不友好的情况
import sun.misc.BASE64Encoder;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
/**
* 下载工具类
* 用于解决下载时显示的中文文件名称的问题
* */
public class DownloadUtil {
public static String getFileName(String agent,String filename) throws UnsupportedEncodingException {
if (agent.contains("MSIE")){
//IE 浏览器
filename = URLEncoder.encode(filename,"utf-8");
filename = filename.replace("+"," ");
}else if (agent.contains("Firefox")){
//火狐浏览器
BASE64Encoder base64Encoder = new BASE64Encoder();
filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
}else {
//其他浏览器
filename = URLEncoder.encode(filename,"utf-8");
}
return filename;
}
}
效果展示