一、ServletContext对象简介
ServletContext 是应用上下文对象。每一个应用中只有一个 ServletContext 对象, 这个ServletContext 对象被所有Servlet所共享.
在 Servlet 规范中,一共有 4 个域对象。ServletContext 就是其中的一个。它也是 web 应用中最大的作用域,也叫 application 域。它可以实现整个应用之间的数据共享!
生命周期:应用一加载则创建,应用被停止则销毁。
二、ServletContext对象的获取
1、通过request对象获取
ServletContext servletContext1 = req.getServletContext();
System.out.println("servletContext1 = " + servletContext1);
2、通过HttpServlet获取
ServletContext servletContext2 = this.getServletContext();
System.out.println("servletContext2 = " + servletContext2);
注意:两个ServletContext是同一个对象,在一个应用中, ServletContext对象是唯一的!
三、ServletContext对象的作用
1、作为域对象
域对象指的是对象有作用域。也就是有作用范围。域对象可以实现数据的共享。不同作用范围的域对象,共享数据的能力也不一样。
在 Servlet 规范中,一共有 4 个域对象。ServletContext 就是其中的一个。它也是 web 应用中最大的作用域,也叫 application 域。它可以实现整个应用之间的数据共享!
返回值 方法名 说明 void setAttribute(String name,Object value) 向域对象中存储数据 Object getAttribute(String name) 通过名称获取域对象中的数据 void removeAttribute(String name) 通过名称移除域对象中的数据
2、代码实现ServletContext对象
//获取ServletContext对象 ServletContext作为域对象存储数据 //ServletContext context1 = this.getServletContext();//获取ServletContext对象 ServletContext context = req.getServletContext();
3、向ServletContext对象存储数据
//向ServletContext对象存储数据 context.setAttribute("sex","女孩");
4、从ServletContext对象中获取数据
//从ServletContext对象中获取数据 Object sex = context.getAttribute("sex");
5、从ServletContext对象中删除数据
context.removeAttribute("sex");
6、根据文件名获取MIME类型
//获取ServletContext对象
ServletContext context = req.getServletContext();//根据文件名获取MIME类型
String mimeType = context.getMimeType("a.html");
//mimeType = text/html
System.out.println("mimeType = " + mimeType);
四、获取文件的真实(服务器)路径
真实路径也叫服务器路径。举个例子,你在本地工作空间里存储着一份你的项目,同时你在你的服务器上也存储着同样的项目。那么你访问的时候是访问本地空间里的项目呢,还是访问服务器上的项目。显然是服务器上的路径。所以 真实路径也叫服务器路径。
返回值 方法名 说明 String getRealPath(String path) 获取文件的真实路径
1、项目结构
2、获取web目录下的资源
//获取ServletContext对象 ServletContext context = req.getServletContext(); //获取web目录下的资源 String path = context.getRealPath("/b.txt");
3、WEB-INF目录下的资源
//获取ServletContext对象
ServletContext context = req.getServletContext();String path1 = context.getRealPath("/WEB-INF/c.txt");
4、获取src目录下的资源
//获取ServletContext对象
ServletContext context = req.getServletContext();//获取src目录下的资源
String path2 = context.getRealPath("/WEB-INF/classes/a.txt");
五、文件下载案例
1、文件下载需要:
1、页面显示超链接
2、点击超链接后弹出下载提示
3、完成图片文件下载
2、实现步骤:
1、定义页面,编辑超链接href属性,指向Servlet,传递资源名称filename
2、定义Servlet, 实现下载功能
3、获取文件名称
4、使用字节输入流加载文件进内存
5、指定response的响应头: content-disposition:attachment;filename=xxx
6、将数据写出到response输出流
3、文件名中文乱码问题
文件名为中文, 下载时文件名显示错误
解决思路:
1. 获取客户端使用的浏览器版本信息
2. 根据不同的版本信息,设置filename的编码方式不同
提供的工具类:
4、代码实现:
工具类:
package com;
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;}
}
实现下载
package com;import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;/*** @author 86136*/
@WebServlet("/download")
public class FileName extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doPost(req, resp);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1、获取文件名称String filename = req.getParameter("filename");//2、获取ServletContext对象ServletContext servletContext = req.getServletContext();//3、根据文件名获取文件真实路径String path = servletContext.getRealPath("/img/" + filename);//使用缓冲字节流根据路径读取文件/*FileInputStream inp = new FileInputStream(path);*/BufferedInputStream inp = new BufferedInputStream(new FileInputStream(path));//4、指明文件MIME类型String mimeType = servletContext.getMimeType(filename);//5、设置响应的MIME类型resp.setContentType(mimeType);/*resp.setHeader("content-type",mimeType);*///5.1、获取浏览器信息String header = req.getHeader("user-agent");//5.2、解决中文名乱码问题, 根据浏览器类型,重新对文件名编码filename = DownLoadUtils.getFileName(header, filename);//6、以下载的方式打开 context-disposition:我这里必须大写才能下载到本地不知道为什么/*resp.setHeader("context-disposition","attachment;filename="+filename);*/resp.setHeader("Content-Disposition","attachment;filename=" + filename);//7、将数据写入到respServletOutputStream out = resp.getOutputStream();int len=0;while ((len = inp.read())!=-1){out.write(len);}/*byte[] buffer = new byte[1024*8];while ((len = inp.read(buffer)) != -1) {out.write(buffer, 0, len);}*/inp.close();out.close();}
}
html文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body><a href="/img/美女.jpg">美女图片</a><br><a href="/img/诛仙.mp4">诛仙</a><br><a href="/download?filename=美女.jpg">美女图片下载</a><br><a href="/download?filename=诛仙.mp4">诛仙下载</a><br>
</body>
</html>