1. ServletContext 对象的概念
ServletContext 对象代表整个 Web 应用,它可以和 Web 容器通信。
2. ServletContext 对象的获取
-
通过 Request 对象获取
request.getServletContext();
-
通过 HttpServlet 获取
this.getServletContext();
3. ServletContext 对象的功能
-
获取 MIME 类型
-
MIME 类型的概念
MIME 类型是在互联网通信过程中定义的一种文件数据类型,它是文件类型的标准
-
MIME 类型的格式
大类型/小类型
例如:
text/html image/jpeg
-
获取 MIME 类型的方法
- String getMimeType(String file)
-
获取 MIME 类型练习
@WebServlet("/ServletContextDemo2") public class ServletContextDemo2 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取 ServletContext 对象 ServletContext servletContext = this.getServletContext(); // 定义文件名称 String filename = "a.jpg"; // 获取 MIME 类型 String mimeType = servletContext.getMimeType(filename); System.out.println(mimeType); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } }
运行结果:
image/jpeg
-
-
域对象
-
域对象的功能
用来共享数据
-
共享数据的范围
所有用户所有请求的数据
-
方法
- 存储数据
- void setAttribute(String name,Object obj)
- 通过键获取值
- Object getAttribute(String name)
- 通过键移除键值对
- void removeAttribute(String name)
- 存储数据
-
共享数据的练习
实现 ServletContextDemo3 和 ServletContextDemo4 共享数据
@WebServlet("/ServletContextDemo3") public class ServletContextDemo3 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取 ServletContext 对象 ServletContext servletContext = this.getServletContext(); // 存储数据 servletContext.setAttribute("value1","hello"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } }
@WebServlet("/ServletContextDemo4") public class ServletContextDemo4 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取 ServletContext 对象 ServletContext servletContext = this.getServletContext(); // 获取数据 Object value1 = servletContext.getAttribute("value1"); System.out.println(value1); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } }
-
-
获取文件的真实(服务器)路径
-
方法
- String getRealPath(String path)
-
获取文件的真实路径练习
@WebServlet("/ServletContextDemo5") public class ServletContextDemo5 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取 ServletContext 对象 ServletContext servletContext = this.getServletContext(); // 获取 web 目录下的 c.txt 的真实路径 String realPath1 = servletContext.getRealPath("a.txt"); System.out.println(realPath1); // 获取 WEB-INF 目录下的 b.txt 的真实路径 String realPath2 = servletContext.getRealPath("/WEB-INF/b.txt"); System.out.println(realPath2); // 获取 src 目录下的 c.txt 的真实路径 String realPath3 = servletContext.getRealPath("/WEB-INF/classes/b.txt"); System.out.println(realPath3); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } }
-
4. 文件下载案例
-
需求分析
- 页面显示超链接
- 点击超链接后弹出下载提示框
- 完成图片文件下载
-
详细设计
- 定义页面,编辑超链接 href 属性,指向 Servlet,设置请求参数,传递文件名称
- 定义 Servlet
- 获取请求参数,文件名称
- 使用字节输入流加载文件进内存
- 设置 response 的响应头
- 将输入流数据写出到 response 输出流
-
编码实现
-
定义页面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <a href="/DownloadServlet?filename=1.jpg">图片1</a> <a href="/DownloadServlet?filename=2.jpg">图片2</a> </body> </html>
-
定义 Servlet
@WebServlet("/DownloadServlet") public class DownloadServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1.获取请求参数,文件名称 String filename = request.getParameter("filename"); // 2.使用字节输入流加载文件进内存 // 2.1 找到文件的真实路径 ServletContext servletContext = this.getServletContext(); String realPath = servletContext.getRealPath("/img/"+filename); // 2.2 用字节流关联 FileInputStream fileInputStream = new FileInputStream(realPath); // 3. 设置 Response 的响应头 // 3.1 获取文件类型 String mimeType = servletContext.getMimeType(filename); // 3.2 设置响应头类型 response.setHeader("Content-type",mimeType); // 3.3 设置响应头打开方式 response.setHeader("Content-disposition","attachment;filename="+filename); //4.将输入流的数据写出到 response 输出流中 ServletOutputStream outputStream = response.getOutputStream(); byte[] buff = new byte[1024 * 8]; int len = 0; while((len = fileInputStream.read(buff)) != -1){ outputStream.write(buff,0,len); } fileInputStream.close(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } }
-
-
中文文件问题
-
问题
如果文件名是中文,下载后的文件名称无法显示
-
解决思路
- 获取客户端使用的浏览器版本信息
- 根据不同的版本信息,设置 filename 的编码方式不同
-
解决步骤
-
创建一个 utils 包,在其中创建一个工具类 DownLoadUtils,它可以根据浏览器设置 filename 的编码
package com.zt.web.utils; import sun.misc.BASE64Encoder; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; public class DownLoadUtils { 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; } }
-
在 Servlet 中使用工具类方法编码文件名
@WebServlet("/DownloadServlet") public class DownloadServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1.获取请求参数,文件名称 String filename = request.getParameter("filename"); // 2.使用字节输入流加载文件进内存 // 2.1 找到文件的真实路径 ServletContext servletContext = this.getServletContext(); String realPath = servletContext.getRealPath("/img/"+filename); // 2.2 用字节流关联 FileInputStream fileInputStream = new FileInputStream(realPath); // 3. 设置 Response 的响应头 // 3.1 获取文件类型 String mimeType = servletContext.getMimeType(filename); // 3.2 设置响应头类型 response.setHeader("Content-type",mimeType); // 3.3 解决中文文件名问题 // 3.3.1.获取 user-agent 请求头 String agent = request.getHeader("user-agent"); // 3.3.2.使用工具类方法编码文件名即可 filename = DownLoadUtils.getFileName(agent, filename); // 3.4 设置响应头打开方式 response.setHeader("Content-disposition","attachment;filename="+filename); //4.将输入流的数据写出到 response 输出流中 ServletOutputStream outputStream = response.getOutputStream(); byte[] buff = new byte[1024 * 8]; int len = 0; while((len = fileInputStream.read(buff)) != -1){ outputStream.write(buff,0,len); } fileInputStream.close(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } }
-
-