Web | Servlet三大作用域
前提概要:
三大域(作用范围从小到大):Request域 < Session域 < Application域这些域都对应着一个对象,由于对象在某个时间范围内一直存在,所以存储的数据也一直存在,因此可以作为存储数据的域来使用。他们存在作用时间范围也意味着只有在这个时间范围内可以借助这个域对象进行数据共享。当然这些对象不是你创建的,你只需要获取就可以了,你可以把它当做一个全局的变量,在其存活的时间范围内,只要你可以获取到这个对象你就可以使用它。
下面说的request对象是指实现相应接口创建的对象,并不具体指哪一个!
1. request域
1.1 request域对应的真实类型:
HttpServletRequest
:这个类型接口再熟悉不过了,服务器软件通常会实现这个接口,创建对象(request对象),用来封装请求数据。
request域对象如何获取?
原生Servlet在方法形参中已经提供了,你只需要调用,后续服务器软件(或者说Servlet容器)会帮你生成的。在一些框架的处理器方法中,你也可以直接加上形参,方法体内调用,Servlet容器会帮你实现的。
//原生Servlet
@WebServlet("/responseServlet")
public class ResponseServletDemo2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//request调用即可后续服务器软件(或者说Servlet容器)会帮你生成的
}
}
这个接口中还提供了如下方法用于存储数据:
1.2 request域对象中存储、获取、删除数据:
返回值 | 方法名称 | 方法介绍 |
---|---|---|
void | setAttribute(String name,Object obj) | 存储数据到request中 |
Object | getAttitude(String name) | 通过request中的键获取对应的值 |
void | removeAttribute(String name) | 通过键删除数据 |
1.3 范围:
一次请求中有效,即一次浏览器请求中对象一直存在。这里着重理解这个请求,你在这个请求中想获取其它request域对象(比如其它浏览器也在访问这个服务器也会建立request域对象)是获取不到的,所以也获取不到对应数据。你想获取之前你请求中的同样不可能,因为已经销毁了。
为什么?
服务器在每次请求中会建立相应新的request对象来封装请求数据,当然你请求换了意味着这个对象会被销毁,在另一个请求中又是新的对象。所以你存在对象中的数据也就没了。
有什么用?
以对象来讲:他提供了一些其它方法。
以域来讲:在这个时间范围内你可以获取这个对象取出其中的资源信息,比如请求转发的案例再贴切不过了。
当然后者是基于前者来实现的,也可以说互相作用,具体的功能可以看看:request和response。
2. session域
session域?他和我们说的cookie、seesion中的session有什么区别?
没什么区别,都是一个东西。
2.1 session域对应的真实类型
真实类型
HttpSession
如何获取?
通过request对象获取:HttpSession session = request.getSession()
同样它也提供了很多方法供你对数据增删改查。
2.2 存储、获取、删除数据
返回值 | 方法名称 | 方法介绍 |
---|---|---|
void | setAttribute(String name,Object obj) | 存储数据 |
Object | getAttribute(String name) | 通过键获取值 |
void | removeAttribute(String name) | 通过键删除数据 |
2.3 范围
范围:在一次会话中,每次会话开始时服务器会创建一个对象,会话结束时对象会被销毁,这里着重理解这个会话,和上面request域的分析差不多。
什么叫一次会话?
一个浏览器一个服务器进行多个请求过程就是一个会话,浏览器没关闭,服务器没挂掉,当然你也可以另外设置Seesion的的存活时间;
有什么用?
以对象来讲:他提供了很多方法。
以域来讲:一个会话范围内共享数据,如用户登录信息,当然这只是作为域的作用。
当然后者是基于前者来实现的,也可以说互相作用。当然,这里只是和其它域对比起来简单的说了一下,想了解Seesion和Cookie看我的这篇文章:Session 和 Cookie
2.4 其它特点
- session可以存储任意类型,任意大小的数据
- session用于存储一次会话的多次请求的数据,存在服务器端
3. application域
3.1 application域对应的真实类型
真实类型
ServletContext
如何获取?
- 通过request对象获取
ServletContext sc = request.getServletContext();
- 通过HttpServlet获取
ServletContext sc = this.getServletContext();
@WebServlet("/responseServletDemo2")
public class ResponseServletDemo2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 获取ServletContext对象
ServletContext context = this.getServletContext();
//2. 获取ServletContext对象
ServletContext sc = request.getServletContext()
}
}
3.2 request域对象中存储、获取、删除数据方法:
返回值 | 方法名称 | 方法介绍 |
---|---|---|
void | setAttribute(String name,Object obj) | 存储数据 |
Object | getAttribute(String name) | 通过键获取值 |
void | removeAttribute(String name) | 通过键删除数据 |
3.3 范围:
整个web项目应用存活的时间内,项目启动时,服务器就会建立这个对象,服务器关闭才销毁这个对象,这意味着在整web项目存活期间都可以使用,只要你能获取到对象。
3.4 作为对象的常见作用
1. 获取MIME类型
返回值 | 方法名称 | 方法介绍 |
---|---|---|
String | getMimeType(String file) | 获取文件的MIME类型 |
原理:
这个方法是通过文件名的后缀来判断的,这个对象是服务器软件(tomcat为例)实现创建的,tomcat在web.xml文件中有后缀名和MIME类型的一个对应,tomcat会去这个文件中找,然后返回给你。你要是足够有勇气,可以试着把web.xml中的删掉看会发生什么。
2. 读取文件
返回值 | 方法名称 | 方法介绍 |
---|---|---|
String | getRealPath(String path) | 获取项目下文件的磁盘绝对路径,注意这个只能获取到项目文件夹的路径,你可以理解为就是虚拟地址映射的项目路径。剩下的路径是你给的路径拼接上去的,具体如下面的例子 |
InputStream | getResourceAsStream(String path) | 获取项目下文件的输入流 |
@WebServlet("/responseServletDemo2")
public class ResponseServletDemo2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 获取ServletContext对象
ServletContext context = this.getServletContext();
//web目录下资源访问(对应web项目文件夹)
String b = context.getRealPath("/b.txt");
System.out.println(b);
//WEB-INF目录下的资源访问(对应web项目文件夹下的WEB-INF目录)
String c = context.getRealPath("/WEB-INF/c.txt");
System.out.println(c);
//src目录下的资源访问(对应web项目文件夹下的WEB-INF目录下的classes文件夹下的资源)
String a = context.getRealPath("/WEB-INF/classes/a.txt");
System.out.println(a);
//获取web目录下的资源返回输出流
InputStream is = context.getResourceAsStream("/b.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String s = reader.readLine();
while(s!=null){
System.out.println(s);
}
}
}