session 会话
session也是用来存储多次请求之间的状态信息,session是把这些信息存在服务器的内容当中,只限于同一时间的同一浏览器中。
1 session创建
HttpSession session = request.getSession();
// 首次调用getSession方法就是创建session对象
// 后续再调用getSession方法是获取第一次创建好的session对象
@WebServlet(urlPatterns = "/s3")
public class session1 extends HttpServlet{
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取session对象
HttpSession session = req.getSession();
//存入信息
session.setAttribute("name","张三");
//提示语,向浏览器返回一个值
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().print("session 已经建立");
}
}
存入内容
session.setAttribute(“变量名”, 任意信息);
获取内容
Obejct 信息 = session.getAttribute(“变量名”);
删除内容
Obejct 信息 = session.removeAttribute(“变量名”);
让session失效(会清空session中所有内容)
session.invalidate();
2 典型应用-用户登录
登录界面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/login" method="post">
<input type="text" name="username" placeholder="请输入用户名">
<input type="password" name="password" placeholder="请输入密码">
<input type="submit" value="登录">
</form>
</body>
</html>
获取提交的值
@WebServlet(urlPatterns ="/s5")
public class LoginServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//编码,防止post方式提交的中文信息,需要设置格式,否则会乱码
req.setCharacterEncoding("utf-8");
//获得表单或者地址栏提交的信息
String username = req.getParameter("username");
String password = req.getParameter("password");
//判断提交的的姓名和密码是否正确
if(username.equals("张三")&&password.equals("123")){
//如果正确,创建session,session的创建方法不是new,需要和创建cookie区分
HttpSession session = req.getSession();
//存储登录标记
session.setAttribute("login","aaa");
//将获取的值放入作用域
session.setAttribute("username",username);
//姓名和密码正确就进入欢迎界面
req.getRequestDispatcher("huanying.jsp").forward(req,resp);
}
//否则继续进入登录界面,重新输入,知道输入并提交正确的姓名和密码
else {req.getRequestDispatcher("login.jsp").forward(req,resp);
}
}
}
欢迎界面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
您已经成功登录,欢迎您<%=session.getAttribute("username")%>
<hr>
欢迎您: ${sessionScope.username}
</body>
</html>
删除界面,登录成功后,才可以验证登录标记 if(session.getAttribute(“login”)==null,这是引出一个问题,如果我们换一个浏览器执行下列代码,浏览器则无响应,再一次证明session必须在同一浏览器下执行。
@WebServlet(urlPatterns = "/s6")
public class delete extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
if(session.getAttribute("login")==null){
req.getRequestDispatcher("login.jsp").forward(req,resp);
}
else {
System.out.println("删除成功");
}
}
}
3 典型应用-用户注销(安全退出)
@WebServlet(urlPatterns = "/logout")
public class LogoutServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
session.invalidate(); // 让session失效(让内容全部清空)
req.getRequestDispatcher("login.jsp").forward(req,resp);
}
}
4 jsp页面获取session中的变量
${sessionScope.变量名}或者<%=session.getAttribute(“变量名”)%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
您已经成功登录,欢迎您<%=session.getAttribute("username")%>
<hr>
欢迎您: ${sessionScope.username}
</body>
</html>
5 session实现的原理
session 必须针对同一个浏览器,才能实现在请求存储信息,在之后的请求获取信息的效果
每个用户访问服务器时,服务器会为他们创建一个独立的session
- 首次创建session时,tomcat会产生一个名为
JSESSIONID=session的唯一标识
的特殊cookie
这个JSESSIONID=1
就会随着响应返回给浏览器 - 浏览器会记录这个cookie。之后的所有请求会把此cookie发送给服务器。
服务器根据cookie的值找到对应的session - jsessionid 这个cookie属于会话cookie,浏览器关闭就会消失
对比session和cookie
- session是将信息存储于服务器端,cookie是将信息存储于浏览器端
- session与cookie相比,更为安全
- session的生命周期相对较短,
两次请求间隔超过30分钟,服务器会销毁session
调用session.invalidate方法时,会立刻销毁
cookie
会话cookie是浏览器关闭就销毁
setMaxAge的cookie会根据设置的寿命存活一段时间 - 存储的信息量上
cookie 每个最大大小是4k左右
session 理论上没有限制,但session要占用服务器内存,所以不太适合存储太多的内容
信息要永久存储,还是需要使用数据库 - cookie里数据都得是字符串,而session里可以存储任意类型
6. 重定向请求
请求转发:
request.getRequestDispatcher(“目录路径”).forward(request,response);
请求重定向:
response.sendRedirect(“目录路径”);
@WebServlet(urlPatterns = "/s7")
public class Servlet1 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//便于观察进入servlet1
System.out.println("进入第一层");
//使用req作用域存值
req.setAttribute("name","zhangsan");
//采用请求转发跳转到/s8
req.getRequestDispatcher("/s8").forward(req,resp);
//重定向可以获取session作用域的值
HttpSession session = req.getSession();
session.setAttribute("name","zhangsan");
//重定向到/s8
resp.sendRedirect("/s8");
}
}
@WebServlet(urlPatterns = "/s8")
public class Servlet2 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//便于观察进入了servlet2
System.out.println("进入第二层");
//获取并打印在作用域中得到值,采用请求转发的值可以获取,重定向无法获取req作用域中的值
System.out.println(req.getAttribute("name"));
//重定向可以获取session作用域的值
HttpSession session = req.getSession();
System.out.println(session.getAttribute("name"));
}
}
7. Session 和Cookie的区别
- 请求转发时,地址栏不会改变(是第一个servlet的地址)
重定向,地址栏会发生变化(是最后一个servlet的地址) - 请求转发时一次请求,跳转发生在服务器内部
重定向是两次请求,第一次请求会返回302的状态码和目标地址,
浏览器根据目标地址发送第二次请求,才完成整个流程 - 重定向是两次请求,所以不能利用request作用域存值取值
但可以使用session作用域来存值取值,session只要在一个浏览器就可以。
请求转发因为是同一次请求,所以可以使用request作用域存值取值 - 请求转发的目标只能是本项目的servlet或jsp
重定向跳转的目标可以是任意的
8. 经验
如果执行查询操作
如servlet --> jsp // 关系密切的跳转使用请求转发 req.getRequestDispatcher("").forward(req,resp);
如果执行删除操作
删除servlet --> 查询列表servlet // 关系不密切的跳转使用重定向 resp.sendRedirect("");