目录
1 ServletContext对象
ServletContext代表整个web应用,可以和程序的容器(服务器)来通信,功能如下:
- 获取MIME类型;
- 域对象:共享数据;
- 获取文件的真实路径(服务器路径);
ServletContextd的获取方式:
- 通过request对象获取,request.getServletContext();
- 通过HttpServlet获取,this.getServletContext();
@WebServlet("/servletContextDemo1")
public class ServletContextDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//ServletContext对象的获取
//通过request对象获取
ServletContext context1 = request.getServletContext();
//通过HttpServlet获取
ServletContext context2 = this.getServletContext();
System.out.println(context1);
System.out.println(context2);
System.out.println(context1==context2); //true
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
1.1 获取MIME类型
MIME类型,是在互联网通信过程中定义的一种文件数据类型:
- 格式:大类型/小类型,如 text/html image/jpeg
- 获取方法:String getMIMEType(String file)
@WebServlet("/servletContextDemo2")
public class ServletContextDemo2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//ServletContext功能
ServletContext context = this.getServletContext();
//定义文件名称
String fileName = "a.jpg";
String mimeType = context.getMimeType(fileName);
System.out.println(mimeType); //image/jpeg
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
1.2 域对象:共享数据
1)setAttribute(String name, Object value)
2)getAttribute(String name)
3)removeAttribute(String name)
ServletContext的对象范围是最大的,可以共享所以用户的数据,如下举例,在demo3中设置数据,在访问demo4,可以看见打印的hello。
注意:因为范围比较大,且生命周期很长(跟随服务器的启用和关闭),所以应用时一定要谨慎。
@WebServlet("/servletContextDemo3")
public class ServletContextDemo3 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//ServletContext功能
ServletContext context = this.getServletContext();
//设置数据
context.setAttribute("msg","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 context = this.getServletContext();
//获取数据
Object msg = context.getAttribute("msg");
System.out.println(msg);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
1.3 获取文件的真实路径
方法:String getRealPath(String path)
注意src、web、web/WEB-INF不同目录下的资源路径:
@WebServlet("/servletContextDemo5")
public class ServletContextDemo5 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//ServletContext功能
ServletContext context = this.getServletContext();
//获取文件真实路径(服务器路径)
//先在src、web、web/WEB-INF目录下分别建个a.txt、b.txt、c.txt
String b = context.getRealPath("/b.txt"); //web目录下资源访问
System.out.println(b);
// File file = new File(realPath);
String c = context.getRealPath("/WEB-INF/c.txt");//WEB-INF目录下资源访问
System.out.println(c);
String a = context.getRealPath("/WEB-INF/classes/a.txt");//src目录下的资源访问
System.out.println(a);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
2 文件下载案例实战
通过对http请求和响应,以及上一节ServletContext的学习,本章以文件下载作为一个综合案例进行实战练习。
【需求】:
- 1)页面显示超链接
- 2)点击超链接后弹出下载提示框
- 3)完成图片下载
【分析】:
- 1)如果超链接指向的资源可以被浏览器解析,如图片,则会直接在浏览器显示,若不能解析,才会弹出下载提示框;
- 2)需求是任何资源都要弹出下载提示框
- 3)需要使用响应头设置资源的打开方式:content-disposition:attachment;filename=xxx
【实现步骤】:
- 1)定义页面,编辑超链接hred属性,指向servlet,传递资源名filename
- 2)定义servlet:
--获取文件名称;
--使用字节输入流加载文件进内存;
--指定response响应头:content-disposition:attachment;filename=xxx;
--将数据写出到response输出流。
【代码实现】:
在web目录下新建img,其中存放一个图片
download.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="/response/img/test.png">图片</a>
<hr>
<a href="/response/downloadServlet?filename=test.png">图片-跳转至servlet-出现下载提示框</a>
</body>
</html>
DownloadServlet:
@WebServlet("/downloadServlet")
public class DownloadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1、获取请求参数
String filename = request.getParameter("filename");
//2、使用字节输入流加载文件至内存
String realPath = this.getServletContext().getRealPath("/img/" + filename);
FileInputStream fis = new FileInputStream(realPath);
//3、设置response响应头
response.setContentType(this.getServletContext().getMimeType(filename));
response.setHeader("content-disposition","attachment"+filename);
//4、将输入流的数据写出到输出流中
ServletOutputStream sos = response.getOutputStream();
byte[] buff = new byte[1024*8];
int length = 0;
while (fis.read(buff)!= -1){
sos.write(buff,0,length);
}
fis.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
【中文文件名的问题】:若我们把test.png更换为 测试图片.png,会发现问题,且不同浏览器表现不一,解决思路:
1)获取客户端使用的浏览器版本信息;
2)根据不同的版本信息,设置filename编码方式不同
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;
}
}
———————————————————————————————————————
本文为博主原创文章,转载请注明出处!
若本文对您有些许帮助,轻抬您发财的小手,关注/评论/点赞/收藏,就是对我最大的支持!
祝君升职加薪,鹏程万里!