1 请求转发
- servlet作为controller将model(数据)传递给jsp作为的view,就是通过请求转发完成的
- 应用场景:用户密码登录失败时,重新回到登录页面
- 特点
- 客户端只发送一次请求
- 浏览器地址栏没有变化
- 请求过程中,只有一个request和一个response
- 几个servlet共享一个request和一个response
- 对客户端透明,客户端不知道服务器端做了哪些操作
- 方法
//1. 请求servlet时,写相对路径,请求转发语句后面的代码虽然会被执行,但一般不写东西,直接加return退出程序
//2. 此处为转发给另一个servlet,也可以转发给jsp
req.getRequestDispatcher("login").forward(req,resp);
- 请求转发时的不同servlet间的数据共享
//第一个servlet中执行
req.setAttribute("str","用户名或密码错误");
//其他servlet中执行
req.getAttribute("str");
2 重定向
- 应用场景:可以避免表单数据重复提交。这是因为重定向时,地址栏变化了,相当于在新页面重复提交,而新页面并没有表单数据,因此不会重复提交
- 特点
- 浏览器发送两次请求
- 浏览器地址发生变化
- 请求过程中产生两个request和两个response
- 两个servlet无法共享同一组request、response,因此无法使用req.setAttribute共享数据
- 代码
resp.sendRedirect("login");
3 请求转发与重定向区别
请求次数 | 地址栏信息 | 是否共享数据 | 跳转限制 | 发生行为 | |
---|---|---|---|---|---|
请求转发 | 1 | 不变 | 是 | 本站资源 | 服务端 |
重定向 | 2 | 变化 | 否 | 任意URL | 客户端 |
4 Cookie
- 客户端保存数据的技术
4.1 简介
- 为解决HTTP协议无状态的问题而产生,例如利用Cookie实现三天内自动登录
- Cookie是一种在客户端保持HTTP状态信息的技术
- Cookie是在浏览器访问服务器的某个资源时,由web服务器在响应头以"Set-Cookie:key1=value1;key2=value2"的形式传送给浏览器的数据
- 浏览器如果保存了某个cookie,那么以后每次访问服务器时,都会在请求头以"Cookie:key1=value1;key2=value2"的形式传递给服务端
- cookie只能记录key-value形式的信息
- 一个web站点可以给浏览器发送多个cookie,一个浏览器也可以存储多个站点的cookie
4.2 分类
- 临时Cookie:浏览器关闭后消失
- 持久化Cookie:存放在浏览器某目录中,时间过期后失效
4.3 相关操作
- 服务器传递给浏览器Cookie
Cookie cookie = new Cookie("00001","beijing");
//将临时cookie持久化,参数为秒,表示持久化3天
cookie.setMaxAge(3*24*3600);
//向浏览器发送Cookie,此时响应头中,会多出Set-Cookie: 00001=beijing; Expires=Sun, 23-Feb-2020 12:39:27 GMT
//当浏览器再次发送其他请求时,请求头中会多出Cookie:00001=beijing;
resp.addCookie(cookie);
2. 传递多个Cookie
//每一个cookie对象中保存一个key-value键值对的数据,想要存储多个k-v数据,需要创建多个cookie
Cookie cookie = new Cookie("00001","beijing");
Cookie cookie1 = new Cookie("00002","shanghai");
resp.addCookie(cookie);
resp.addCookie(cookie1);
3. 服务端指定Cookie在指定路径时,才发送给服务端
//只有在访问该路径时,浏览器才将cookie由请求头传递给Tomcat
//即http://localhost:8080/myfirstServlet/reqdecode时,请求头中才有Cookie:000002=shanghai
cookie1.setPath("/reqdecode");
- 服务端获取浏览器发送来的Cookie
//服务端获取所有Cookie数据
Cookie[] cookies = req.getCookies();
if(cookies!=null){
for(Cookie c:cookies){
String name = c.getName();
String value = c.getValue();
System.out.println(name+"="+value);
}
}
5 Session
- 解决相同用户发送不同请求时的数据共享问题,由于生命周期不长不短,因此一般只用于存放客户端登录信息
5.1 简介
- 是服务端存储共享数据的技术
- session需要依赖cookie技术
- 服务器为每个用户创建一个独立的Session对象
- 每个session对象的有效时长为30分钟,超时候该对象自动销毁,期间客户端再次访问时,会重置该时间
- 每次关闭浏览器后,重新请求都会开启一个新的session对象,因为返回的JSESSIONID保存在浏览器内存中,是临时Cookie
5.2 机制
- 客户端首次发送请求,服务端为该客户生成新的JSESSIONID和对应的Session,并返回给客户端
- 客户端再次发送请求时,将JSESSIONID放在请求头中,发送给服务端,服务端可以通过该值,在session映射区找到对应的session对象
5.3 相关操作
- 为客户端返回Session对应的Cookie
//1. 不写这句话,也创建session对象,但不会将JSESSIONID存入Cookie,通过响应返回给浏览器
HttpSession session = req.getSession();
//2. 获取JSESSIONID
String id = session.getId();
//3. 可以通过下面得方式让Session也持久化,也就是客户端关闭后,仍能找到之前的Session
//手动创建一个存储JSESSIONID的cookie 设置cookie设置持久化时间
Cookie cookie = new Cookie("JSESSIONID",id);
cookie.setMaxAge(60*60);
2. Session常用方法
//设置session有效市场,单位秒,即每5s重新创建一个session对象,并生成新的JSESSIONID
session.setMaxInactiveInterval(5);
//设置session强制失效
session.invalidate();
//向session中设置参数,通过它就能实现重定向时的数据共享
session.setAttribute("00001","beijing");
//从session中获取参数
session.getAttribute("00001");
6 ServletContext
- 解决不同用户间的数据共享,由于生命周期过长,因此一般只用于存放web.xml中数据,而不存放额外数据
6.1 简介
- 由服务器创建
- 所有用户共享同一个ServletContext对象,该对象中存放着该web项目中的web.xml信息
- 所有servlet,都可以访问到同一个ServletContext中的属性
- 每一个web项目对应的是一个ServletContext
6.2 相关操作
- 获取ServletContext对象的三种方式
ServletContext s1 = this.getServletContext();
ServletContext s2 = this.getServletConfig().getServletContext();
ServletContext s3 = req.getSession().getServletContext();
- 设置、获取属性
//1. 设置属性
s1.setAttribute("00001","zhangsan");
//2. 获取属性值,不同用户、不同servlet,获得的属性值相同
s1.getAttribute("00001");
- 获取web.xml中配置的公共属性
//如果有多组公共属性,使用多个context-param标签
s1.getInitParameter("beijing");
<context-param>
<param-name>beijing</param-name>
<param-value>123456</param-value>
</context-param>
- 获取文件的绝对路径
//E:\IdeaProjects\myfirstServletWu\out\artifacts\myfirstServletWu_war_exploded\web.xml
s1.getRealPath("web.xml");
- 获取web项目的上下文路径
//1. 即虚拟目录路径:/myfirstServlet
s1.getContextPath();
7 ServletConfig
- 方便每一个servlet,在web.xml中获取自己单独的属性配置
- 每个servlet单独拥有一个ServletConfig对象
<servlet>
<servlet-name>HelloWorld</servlet-name>
<servlet-class>control.HelloWorld</servlet-class>
<init-param>
<param-name>china</param-name>
<param-value>beijing</param-value>
</init-param>
</servlet>
- 创建对象、获取属性值、获取属性名的集合
//获取对象
ServletConfig cnf = this.getServletConfig();
//根据key获取value
String value = config.getInitParameter("china");
//获取所有的key
Enumeration<String> initParameterNames = cnf.getInitParameterNames();