这里写目录标题
会话对象HttpSession
HttpSession是tomcat在服务器端为每个浏览器准备的私人储物箱,每个浏览器在tomcat里都有一个属于自己的HttpSession对象,用于存储私人数据。
在Servlet中可以通过request.getSession()方法来获得session对象,这个方法总是返回与发送请求的浏览器对应的session对象。
该方法是有这个对象则用这个对象,没有则创建。用来解决http无状态的问题。该对象保存在服务器中。
Session的私有性
利用session存取私人数据
与request对象一样,session对象也提供了存取数据的方法
session.setAttribute( “name”, object );
name : 数据的别名
object:存储的数据本身
Object session.getAttribute(“name”) ;
name :要获取的数据别名
返回值:与name对应的数据对象
Session对象的生命周期
创建 : 当用户第一次调用getSession(true)方法
销毁 : 用户长时间没有执行操作(timeout)
Tomcat默认的session超时为30分钟
Session的钝化与锐化:
当服务器内存空间紧张或tomcat关闭时,tomcat会将不活跃的session保存到磁盘中,当需要使用时或tomcat重新启动时再次加载到内存中来
Session与request
request
命名属性可以在由forward连接的多个servlet之间共享
生命周期较为短暂
当请求到达服务器时创建
当应答送回到浏览器时销毁
Sesison
命名属性可以在同一个浏览器的多次请求之间共享
生命周期较长
在调用request.getSession(true)时被创建
在超时之后被销毁
Session的实现机制
getSession()方法是如何将session对象与浏览器对应起来的?
Tomcat会为每个拥有session的浏览器设置一个特别的Cookie,称作会话Cookie.会话Cookie的名字固定叫做 “JSESSIONID”, Cookie的值就是该浏览器对应的session ID号,其生命周期为-1。
当调用getSession(true)时,他首先检查用户的会话Cookie是否存在
如果不存在 : 为其创建新的session对象,将session对象的ID保存到新建的会话Cookie中,并将会话cookie送回浏览器 。
如果存在 : 则按照会话Cookie 的值找到对应的session对象返回
Session对象使用实例
登陆成功后将登陆名存储到用户的session对象中
检查登陆的时候,就判断session对象中是否存储了用户的登陆名
如果sessoin保存了用户名:说明该用户已经登陆过
如果sesson没有保存用户名:说明该用户没有登陆
- 创建登录界面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<form action="test" method="post">
账户:<input type="text" name="account"></br>
密码:<input type="text" name="password"></br>
<input type="submit" value="登录">
</form>
</body>
</html>
- post方式进行登录验证将用户数据写入会话中
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("当前请求方式为post方式");
response.setContentType("text/html;charset=utf-8");
//设置请求对象编码 解决post方式的乱码问题
request.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
String username = request.getParameter("username");
String password = request.getParameter("password");
if (username.equals("zhangsan")&&password.equals("123456")){
//创建会话,保存用户信息
HttpSession session = request.getSession();
//设置会话有效期,单位秒,默认有效期30分钟
session.setMaxInactiveInterval(600);
//保存用户帐号
session.setAttribute("username",username);
out.write("<h3>验证成功</h3> 欢迎:"+username+":<a href = \"index\">主页面</a>");
}else {
out.write("<h3 style=\"color:red;\">验证失败</h3>");
}
out.close();
}
- 对会话进行验证
@WebServlet("/index")
public class IndexServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
HttpSession session = request.getSession();
if (session.getAttribute("username")==null){
out.write("请先登录,<a href=\"login.html\">登录</a>");
}else {
out.write("欢迎:"+session.getAttribute("username")+"<a href=\"logout\">注销</a>");
}
}
}
- 销毁会话
@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
//清空会话中的所有数据
session.invalidate();
//如果想移除单个数据可以使用removeAttribute()
// session.removeAttribute("username");
//重定向到登录界面
response.sendRedirect("login.html");
}
}
Cookie
Cookie是服务器保存在用户浏览器上的一段字符串
当浏览器向服务器发送请求时,会自动将这些浏览器存储的字符串发送到服务器
我们可以利用这些字符串记录用户的重要状态,如是否登录,用户权限等
在服务器端的Servlet中,通过检查这些字符串来判断用户的状态
如何将Cookie存储到浏览器
1、创建Cookie
2、设置Cookie的生命周期
3、将Cookie存储在用户的浏览器中
Session和Cookie的使用
@WebServlet("/session")
public class SessionServlet extends HttpServlet {
/**
* servlet生命周期的方法,可以处理所有方式的请求
*/
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//创建会话对象,如果存在使用原来的会话对象,如果不存在则创建新的会话对象。
//会创建会话Cookie,把session的id写入客户的浏览器名称是jsessionid,只是session的id,浏览器下次访问时带上Cookie进行访问
response.setContentType("text/html;charset=utf-8");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
HttpSession session = request.getSession();
PrintWriter out = response.getWriter();
out.write("会话id:" + session.getId() + "</br>");
out.write("会话创建时间:" + sdf.format(new Date(session.getCreationTime())) + "</br>");
out.write("系统当前时间:" + sdf.format(new Date()));
//创建会话对象
Cookie username = new Cookie("username", "zhangsang");
Cookie password = new Cookie("password", "123456");
//设置有效时间,单位是秒 不写默认-1(关闭浏览器后删除)
username.setMaxAge(60);
//把Cookie写入浏览器,返回给客户端,只有客户端成功响应之后才能将cookie写入浏览器
response.addCookie(username);
response.addCookie(password);
//获取浏览器的Cookie
Cookie[] cookies = request.getCookies();
Arrays.stream(cookies).forEach(cookie -> {
System.out.println("键:"+cookie.getName()+",值:"+cookie.getValue());
});
out.flush();
out.close();//流关闭响应结束
}
}
Cookie的特征
采用字符串的形式存储数据,简单灵活
存储在用户的浏览器上,减少对服务器的压力
对于重要数据而言,存储在浏览器上不够安全
无法存储格式复杂的数据格式,如对象,集合等
Cookie和Session的比较
Cookie是写在浏览器上的
Session是写在服务器上的
Servlet 通信方法
Servlet 访问网络资源以满足客户端请求
Servlet 使用 RequestDispatcher 接口的 forward() 和include() 方法访问网络资源
public void forward (ServletRequest req, ServletResponse res);
将请求从一个 Servlet 转送到同一个服务器上的另一个 Servlet
public void include (ServletRequest req, ServletResponse res);
在一个 Servlet 中包含另一个 Servlet 的内容
Servlet使用实例
Test1
@WebServlet("/test1")
public class Test01Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setAttribute("name","张三");
//把请求转到/test2,客户端显示的还是第一个请求地址,因为请求转发是发生在服务器内部的事情,客户端不知情
//是同一个请求对象中的转发,两个servlet可以共享request对象的数据
request.getRequestDispatcher("/test2").forward(request,response);
}
}
Test2
@WebServlet("/test2")
public class Test02Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("姓名:"+request.getAttribute("name"));
//调用Test3Servlet的service方法
request.getRequestDispatcher("test3").include(request,response);
System.out.println("年龄:"+request.getAttribute("age"));
}
}
Test3
@WebServlet("/test3")
public class Test03Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setAttribute("age","20");
}
}
forward()方法个include()方法的区别
forward()方法是跳到另一个servlet去处理数据后面的语句不再执行,只能调用一次。
include()方法是调用另一个servlet的方法来获取数据,可以多次调用。
Servlet 上下文
将所有 Servlet 所共有的属性和资源存储于 ServletContext 接口对象。
服务器启动时创建,关闭时销毁
实例:
创建一个类demo01和类demo02,demo01往上下文添加数据,demo02读取数据
demo01:
@WebServlet("/demo01")
public class Demo01Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取上下文对象,该对象在服务器启动时创建,关闭时销毁
ServletContext context = request.getServletContext();
//在上下文对象设置值,所有servlet对象都能够取到。
context.setAttribute("phone","138123456789");
context.setAttribute("address","南宁市西乡塘区");
}
}
demo02:
@WebServlet("/demo02")
public class Demo02Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取上下文对象,该对象在服务器启动时创建,关闭时销毁
ServletContext context = request.getServletContext();
//在上下文对象获取值
System.out.println("电话:"+context.getAttribute("phone"));
System.out.println("地址:"+context.getAttribute("address"));
}
}
小结
* servlet生命周期:
* 单例模式,一个servlet类只创建一个对象,在客户端第一次请求时在服务器创建,用来处理客户端请求。
* 内存不足或者服务器关闭时销毁
* request生命周期:
* 多例模式,每次请求创建一个对象,当请求到达服务器时由服务器创建,当服务器响应结束后返回客户端时销毁。
* session生命周期
* 客户端请求服务器调用getSession方法时由服务器创建,有效期超时或者服务器关闭销毁。
* context生命周期
* 单例模式:服务器启动时创建,服务器关闭时销毁。
* Cookie生命周期
* 服务器响应客户时由服务器创建,响应结束后返回返回客户端浏览器保存对象。
* 如果设置有效期,有效期结束后由浏览器删除,默认是关闭服务器则删除。
总结
可以使用会话跟踪对客户端发出的一系列请求进行跟踪
不同的会话跟踪技术包括用户授权、隐藏表单字段、URL 重写和 Cookie
Servlet 使用 RequestDispatcher 接口的 forward() 和 include() 方法进行通信
Servlet 上下文用于存储不同 Servlet 的信息
ServletConfig 接口的 getServletContext() 方法用于配置 Servlet 上下文(获取上下文)