多个Servlet之间调用规则
前提条件
- 某些来自于浏览器发送的请求,往往需要服务端中多个Servlet协同处理。
- 但是浏览器一次只能访问一个Servlet,导致用户需要多次发起请求,才能的到结果
-
提高用户使用感受规则
无论本次请求设计到多个Servlet,用户只需要通知一次浏览器发起一次请求即可
多个Servlet之间调用规则
重定向解决方案
- 请求转发解决方案
重定向解决方案
工作原理
- 用户第一次通过手动的方式,通知浏览器访问 OneServlet,当OneServlet执行完毕后,将TwoServlet地址写道响应头中的 location属性中
- 导致tomcat将302的状态码,写入状态行中。
- 在浏览器接收到响应包之后,会读取到302状态。此时浏览器自动根据响应头的location属性地址发起第二次请求,访问TwoServlet去完成请求中的剩余任务
实现命令
response.sendRedirect(“请求地址”); // 将地址写入响应包中的响应头中location属性中地址格式:/myWeb/two /网站名/资源文件名
特征
请求地址
- 既可以把当前网站内部的资源文件地址发给浏览器 (/网站名/资源名)
又可以把其他网站资源文件地址发送给浏览器(http://ip:端口号/网站名/资源名)
请求次数
浏览器至少发送两次请求,只有第一次请求是用户手动发送的,后续的都是浏览器自动发送的
请求方式
TwoServlet的请求方式是get
- 重定向的解决方案中,通过地址栏通知浏览器发起下一次请求,所以是get
-
缺点
重定向结局方案需要在浏览器与服务器之间进行多次的往返,大量的时间消耗在往返的次数,增加用户等待服务时间
请求转发解决方案
工作原理
- 用户第一次通过手动方式请求浏览器访问OneServlet. OneServlet工作完毕后,通过当前的请求对象代替浏览器向Tomcat发送请求,申请调用TwoServlet
- Tomcat在接收这个请求之后,自动调用TwoServlet来完成剩余任务
实现命令
RequestDispatcher report = request.getRequestDispatcher(“/资源文件名称”); // 通过当前请求对象生成资源文件申请报告对象
一定要/ 开头
report.forward(当前请求对象,当前的响应对象) //将报告对象发送给Tomcat优点
- 无论本次请求涉及多少个servlet,用户只需要手动的发起一次请求
servlet之间的调用发生在服务端计算机中,节省了服务端和浏览器之间往返次数
特征
请求次数
- 在请求转发过程中,浏览器只发送了一次请求
- 请求地址
- 只能向tomcat服务器申请调用当前网络下资源文件地址(不要写网站名)
- request.getRequestDispathcer(“/资源文件名”)
- 请求方式
- 与浏览器所发送的请求方式一致
数据共享
概述
OneServlet执行完毕后,将产生的数据交给TwoServlet使用
四种数据共享方案
- ServletContext 接口
- Cookie类
- HttpSession 接口
- HttpServletRequest接口
ServletContext接口
介绍
- 来自于Servlet规范中的一个接口。在tomcat中存在 servlet-api.jar
- 在tomcat中负责提供这个接口实现类
- 如果两个Servlet来自同一个网站,那么他们彼此之间就可以通过ServletContext实例对象实现数据共享
-
工作原理
每一个网站里面都存在一个全局作用域对象
- 全局作用域对象 【相当于】 map集合【键值对】可看作为一个公共的留言板
在这个网站中 ,OneServlet可以将一个数据存入到全局作用域对象,当前网站中其他的Servlet都可以从这个全局作用域对象中得到这个数据
生命周期
在Http服务器启动的过程中,自动为当前网站在内存中创建一个全局作用域对象
自动创建 就单独一个
- 在http服务器运行下 全局作用域对象存活状态 | http服务器关闭,全局作用域销毁。
命令实现
同一个网站 OneServlet将数据共享给TwoServlet
public class OneServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.通过请求对象向Tomcat索要当前网站中的【全局作用域对象】
ServletContext application = request.getServletContext();
//2.将数据添加到全局作用域当中 作为共享数据
application.setAttribute("key1","Hello World");
}
}
在TwoServlet里面访问 已经保存好的key1对应的值
public class TwoServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//得到全局作用域对象
ServletContext application = request.getServletContext();
//得到指定关键字的指定数据 返回一个Object类型的数据
Object s = application.getAttribute("key1");
//强转
String ss = (String) s;
//输出到控制台
System.out.println(ss);
}
}
全局作用域对象的变量名 建议叫 application application.removeAttribute(“key1”) // 通过key 删除对应key1的共享数据
Cookie
介绍
- 来自Servlet规范的一个工具类。 存在tomcat提供的servlet-api.jar
- 如果两个Servlet来自于同一个网站,并且为同一个浏览器/用户提供服务时,此时借助于Cookie对象进行数据共享
- Cookie里面存放当前用户的私人数据,在共享数据过程中提高服务质量
-
原理
用户通过浏览器第一次向myWeb 网站发送请求申明OneServlet
- OneServlet在运行期间创建了一个Cookie存储当前用户相关数据
- OneServlet工作完毕后,【将Cookie写入到响应头】交还给当前浏览器
- 浏览器收到响应包之后,将Cookie存储到浏览器的缓存中
- 一段时间之后,用户通过【同一个浏览器】再次向【myWeb网站】发送请求申请TwoServlet时。
- 【浏览器需要无条件的将myWeb网站之前推送过来的Cookie,写入到请求头中】发送过去
- 此时TwoServlet在运行时,就可以通过读取请求头中的Cookie中的信息,得到OneServlet提供的共享数据
实现命令
同一个网站中 OneServlet和TwoServlet借助Cookie来实现数据的共享方案
在OnewServlet中创建一个Cookie
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.创建Cookie对象,保存共享数据(当前用户数据)
Cookie cookie = new Cookie("key","HelloWorld");
//cookie 实际上也是一个map
//一个cookie对象只能放一个键值对
//这个键值对的key和value只能是String(key不能是中文)
//2.把卡交给用户【把cookie写入到响应头中,交给浏览器】
response.addCookie(cookie);
}
TwoServlet中访问Cookie
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//调用请求对象,从请求头中得到浏览器返回的Cookie
//将请求头中的所有cookie封装成一个数组进行返回
Cookie[] cookies = request.getCookies();
//循环遍历数组,得到每一个key和value
for (Cookie c : cookies){
String key = c.getName(); // 读取的是key
String value = c.getValue(); // 读取的是value
System.out.println(key);
System.out.println(value);
}
}
Cookie生命周期
Cookie销毁时机
- 默认的情况下,Cookie存放在浏览器的缓存中
- 只要浏览器关闭,缓存清除,Cookie被销毁
- 在手动设置情况下,可以要求浏览器将接收的Cookie存放在客户端计算机上的硬盘上同时需要去指定Cookie在硬盘上的存活时间。在存活时间范围内,关闭服务器,关闭浏览器,都不会导致Cookie销毁。 存活时间到达Cookie被自动销毁
cookie.setMaxAge(60); //表示当前的cookie对象 在硬盘上存活1分钟【秒】
HttpSession接口
介绍
- 来自于Servlet规范下一个接口,存在于Tomcat中servlet-api.jar
- 其实现类又http服务器提供
- 如果两个Servlet来自于同一个网站,并且为同一个浏览器/用户提供服务时,此时借助于HttpSession对象进行数据共享
开发人员称被HttpSession接口修饰的对象为 【会话作用域对象】
HttpSession和Cookie的区别
存储位置不同
- Cookie:存放在客户端的计算机中【浏览器缓存或者硬盘】
- HttpSession:存放在服务端计算机内存中
- 数据类型不同:
- Cookie:存储的共享数据只能是String
- HttpSession对象可以存储任意类型的共享数据
- 数据的数量
- 一个Cookie 只能存储一个共享数据
- HttpSession 使用map集合共享数据,可以存储任意数量的数据
- 参照物不同
- Cookie相当于服务端的会员卡
- HttpSession 相当于客户在服务端的私人保险柜【大,多】
命令实现
同一个网站下,OneServlet将数据传递给TwoServlet
OneServlet中写入共享数据
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.调用请求对象向Tomcat索要当前用户在服务端的私人储物柜
//返回一个HttpSession对象 程序员们习惯叫他为session
HttpSession session = request.getSession();
//2. 将数据 添加到用户私人储物柜中
session.setAttribute("key1","Hello World");
}
TwoServlet 中读取共享数据
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 访问共享数据
//1.通过请求对象向Tomcat索要用户的私人储物柜
HttpSession session = request.getSession();
//2.从会话作用域对象中,得到OneServlet提供的共享数据(通过key得到value)
//返回一个Object类型的数据
String value = (String)session.getAttribute("key1");
System.out.println(value);
}
Http服务器如何将用户和HttpSession关联起来的呢
- 当用户点击了加入购物车后,服务端执行到OneServlet里面的代码了
- 会看有没有Session 如果没有就会新建一个,并且创建一个Cookie并且返回给浏览器【JSESSIONID = 12452..】
当用户第二次访问的时候 ,请求头里面有一个Cookie 服务端接收到之后,有了ID就开对了箱子 【类似于浴池的手牌】
getSession(); 和getSession(false); 的区别【有参无参】
首先都是索要全局对话作用域对象
getSession();//如果当前用户在服务端中,已经拥有了私人储物柜
- 那么则要求tomcat返回这个私人储物柜
- 如果当前用户尚未拥有自己的私人储物柜,那么Tomcat就会创建一个全新的私人储物柜
在哪些地方出现: 登陆验证(就这一个地方)【用户身份合法 创建一个Session】
**getSession(false)**
//如果当前用户在服务端中,已经拥有了私人储物柜
- 那么则要求tomcat返回这个私人储物柜
- 如果当前用户端在服务端中没有自己的私人储物柜,
- 那么tomcat就会返回一个null
在哪里出现: 其余的资源文件中 都用有参 因为不知道是不是恶意登录
什么时候用有参/无参
当前用户事合法登录的【通过登陆验证】 用无参
-
生命周期
用户和HttpSesion关联使用的Cookie只能存放在浏览器的缓存中
- 在浏览器关闭的时候 意味着用户与HttpSession的关系被切断
- 由于Tomcat无法去监测浏览器何时关闭,因此在浏览器关闭时并不会导致Tomcat将浏览器中的Cookie和HttpSession进行销毁
- 为了解决问题,tomcat会为每一个HttpSession对象设置一个空闲时间【开始——现在】 默认30分钟, 当前Session对象达到30分钟,Tomcat认为用户放弃了自己的Session 此时就会销毁
HttpSession空闲时间的手动设置
当前网站下 / web / WEB-INF/web.xml<session-config>
<!-- 表示当前网站中对大的空闲时间为5分钟,5分后自动销毁-->
<session-timeout>5<session-timeout>
</session-config>
HttpServletRequest接口实现数据共享
介绍
- 如果在同一个网站中两个Servlet之间通过请求转发的方式来进行调用,此时彼此之间将共享同一个请求协议包。而一个请求协议包只对应一个请求对象/响应对象因此servlet之间共享同一个请求对象,此时就可以利用请求对象在两个Servelt之间实现数据共享
- 请求对象可以存放数据【有存放数据的属性 Attribute属性】,响应对象不可以存放数据,所以就可以用请求对象来实现共享
- 在请求对象实现Servlet之间数据共享的功能的时候,开发人员将请求对象叫【请求作用域对象】
实现命令
OneServlet通过请求转发申请调用TwoServelt的时候,需要给TwoServlet提供共享数据
在OneServlet中写入共享数据
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.将数据添加到【请求作用域对象】中的Attribute属性
// value的类型可以是任何类型【map集合 key value】
request.setAttribute("key1","HelloWorld");
//2.向Tomcat申请调用TwoServlet,并别发给tomcat【请求对象,响应对象】
request.getRequestDispatcher("/two").forward(request,response);
}
在TwoSerlet中读取共享数据
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.因为是请求转发,所以TwoServlet使用的请求对象/响应对象和OneServlet使用的是一个
//从当前请求对象中得到OneServlet所写入的共享数据
String s = (String) request.getAttribute("key1");
System.out.println(s);
}