HttpSession入门
1. HttpSession概述
- HttpSession是由JavaWeb提供的,用来会话跟踪的类,保存在服务器端!
- HttpSession是Servlet三大域对象之一(request、session、application(ServletContext)),所以它也有
setAttribute()
,getAttribute()
,removeAttribute()
方法 - HttpSession底层依赖Cookie,或是URL重写!
一个会话内只有一个session,比如说第一次访问服务器时,把session拿过来存点东西。当第二次访问时,获取的还是这个session(期间浏览器没有关闭)。一个请求内一个request,一个会话内一个session
2. HttpSession的作用
- 会话范围:会话范围是某个用户从首次访问服务器开始,到该用户关闭浏览器结束!
>会话:一个用户对服务器多次连贯性请求!所谓连贯性请求,就是该用户多次请求中间没有关闭浏览器! - 服务器会为每个客户端创建一个session对象,session就好比客户在服务器端的账户,它被服务器保存到一个Map中,这个Map被称为session缓存!
>Servlet中得到session对象:HttpSession session = request.getSession();
>jsp中得到session对象:session是jsp内置对象,不用创建就可以直接使用! - session域相关方法(只要是域就都有这三个方法):
>void setAttribute(String name,Object value);
>Object getAttribute(String name);
>void removeAttribute(String name,);
案例1
演示session会话的多次请求中共享数据
1. AServlet:向session域中保存数据
2. BServlet:从session域中获取数据
3. 演示:
> 第一个请求:访问AServlet
public class AServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response){
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
//获取session
HttpSession session = request.getSession();
//向session域中保存信息
session.setAttribute("wangyue","age5");
}
}
首先访问这个Servlet
> 第二个请求:访问BServlet
public class BServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response){
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response){
response.setContentType("text/html;charset=utf-8");
HttpSession session = request.getSession();
//get返回的是Object对象,所以向下转型
String value = (String)session.getAttribute("wangyue");
response.getWriter().print("<h1 style='color:red' align='center'>" + value + "</h1>");
}
}
可以看到当访问BServlet的时候:(只要浏览器不关闭,访问时就一直有值)
案例2
保存用户登录信息
- 案例相关页面和Servlet:
> login.jsp:登录页面
> succ1.jsp:只有登录成功费能访问的页面
> succ2.jsp:只有登录成功费能访问的页面
> LoginServlet:校验用户是否登录成功! - 各页面和Servlet内容:
> login.jsp:提供登录表单,提交表单请求LoginServlet
> LoginServlet:获取请求参数,校验用户是否登陆成功
<>失败:保存错误信息到request域,转发到login.jsp(这个页面显示request域中的错误信息)
<>成功:保存用户信息到session域中,重定向到succ1.jsp页面,显示session域中的用户信息
> succ1.jsp:从session域中获取用户信息,如果不存在,显示“您还没有登录”。存在则显示用户信息
> succ2.jsp:从session域中获取用户信息,如果不存在,显示“您还没有登录”。存在则显示用户信息
用户只要没有关闭浏览器,这个session就一直存在,那么保存在session中的用户信息也就一起存在!那么用户访问succ1和succ2就会通过!
首先写login.jsp:
%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登陆页面</title>
</head>
<body>
<h1 style="color: orange" align="center">请提交登陆信息</h1>
<%
/*
读取Cookie,如果存在则显示到用户名中!
*/
String username = "";
Cookie[] cooks = request.getCookies();
for (Cookie cook: cooks
) {
if ("username".equals(cook.getName()))
username = cook.getValue();
}
%>
<%
String error = (String)request.getAttribute("error");
if (! (error==null)){
out.print("<b><font color='red'>" + error + "</font></b>");
}
%>
<form action="/my2/LoginServlet" method="post">
用户名:<input type="text" name="username" value="<%=username%>"/><br/>
密码:<input type="password" name="password"/><br/>
<input type="submit" value="提交">
</form>
</body>
</html>
然后是LoginServlet:
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response){
//处理中文问题
request.setCharacterEncoding("utf-8");
//获取信息
String username = request.getParameter("username");
String password = request.getParameter("password");
//校验用户名和密码是否正确
if ("jjd".equalsIgnoreCase(username)) { //登陆失败
request.setAttribute("error","用户名或密码错误");
RequestDispatcher rd1 = request.getRequestDispatcher("/login.jsp"); //得到转发器,注意路径上不加项目名!
rd1.forward(request,response); //转发
}
else{ //登陆成功
Cookie cook = new Cookie("username",username); //创建一个Cookie保存到本地,下次访问时,直接将用户名显示
cook.setMaxAge(60*60*24); //设置保存时间
response.addCookie(cook); //保存Cookie
HttpSession session = request.getSession(); //获取session对象
session.setAttribute("username",username); //向session域中保存信息
session.setAttribute("password",password);
response.sendRedirect("/my2/succ1.jsp"); //重定向到succ1.jsp
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response){
doPost(request,response);
}
}
然后是succ1.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>显示信息</title>
</head>
<body>
<h1 align="center">succ1</h1>
<%
String username = (String)session.getAttribute("username");
String password = (String)session.getAttribute("password");
%>
<%
if (username==null || password==null){
request.setAttribute("error","请登陆后查看");
RequestDispatcher rd = request.getRequestDispatcher("/login.jsp");
rd.forward(request,response);
return;
}
%>
<p align="center">您的用户名是:<%=username%></p>
<p align="center">您的密码是:<%=password%></p><hr/>
<a href="/my2/succ2.jsp" target="_blank">点击这里可以访问succ2!</a>
</body>
</html>
然后是succ2.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登陆成功</title>
</head>
<body>
<%
String username = (String) session.getAttribute("username");
String password = (String) session.getAttribute("password");
%>
<%
if (username==null || password==null){
request.setAttribute("error","请登陆后查看");
RequestDispatcher dr = request.getRequestDispatcher("/login.jsp");
dr.forward(request,response);
return;
}
%>
<h1 align="center">恭喜你!通关啦!</h1>
</body>
</html>
HttpSession原理
request.getSession()
方法:服务器不会马上创建session,只有在第一次获取session时才会创建!即request.getSession()
!
- 获取Cookie中sessionId:
<>如果jsessionId不存在,创建session,把session保存起来,把新创建的sessionId保存到Cookie中;
<>如果sessionId存在,通过sessionId查找session对象,如果没有查找到,创建创建session,把session保存起来,把新创建的sessionId保存到Cookie中;
<>如果sessionId存在,通过sessionId查找到了session对象,那么就不会再创建session对象了;在服务器端保存的最大时间是30分钟
<>返回session - 如果创建了新的session,浏览器会得到一个包含了sessionId的Cookie,这个Cookie的生命值是-1,只要不关闭浏览器,这个Cookie就会一直存在
- 下次请求时,再次执行
request.getSession()
方法时,因为可以通过Cookie中的sessionId找到session对象,所以与上次访问时是同一个session对象。 request.getSession(false)
、request.getSession(true)
、request.getSession()
,后面两个方法的效果相同
第一个方法:如果session缓存中(如果Cookie不存在),不存在session,那么返回null,并且不创建session
HttpSession的其他方法
String getId()
:获取sessionId;int getMaxInactiveInterval()
:获取session的最大不活动时间(秒),默认为30分钟。当session在30分钟内没有使用,那么Tomcat会在session池中移除这个sessionvoid invalidate()
:让session失效!调用这个方法会让session失效,当session失效后,客户端再次请求,服务器会为客户端创建一个新的session并在响应中的Cookie添加这个sessionboolean isNew()
:查看session是否为新。当客户端第一次请求时,服务器为客户端创建session,但这时服务器还没有响应客户端,也就是还没有把sessionId发送回来
JSESSIONID是由UUID产生的,Java的util包中提供了产生32位十六进制数的方法:
public void fun{
//调用这个静态方法就会产生UUID的实例
UUID uuid = UUID.randomUUID();
//这样就产生了JSESSIONID
String str = uuid.toString();
//将其中的"-"去掉
String s = str.replace("-","").toUpperCase();
}
在web.xml中配置session的最大不活动时间
数字代表的是时间
<session-config>
<session-timeout>30</session-timeout>
</session-config>
URL重写(理解)
就是把所有的页面中的路径,都使用response.encodeURL(String url)
处理一下。下面是这个方法的原理(把Cookie编程请求参数!)
- session依赖Cookie,目的是让客户端发出请求时归还sessionId,这样才能找到相应的session
- 如果客户端禁用了Cookie,那么就无法得到sessionId,那么session就无用了!
- 也可以使用URL重写来代替Cookie
>让网站的所有超链接、表单中都添加一个特殊的请求参数,即sessionId
>这样服务器可以通过获取请求参数得到sessionId,从而找到session对象。 response.encodeURL(String url)
这个方法会对url进行智能的重写:当请求中没有归还sessionId这个Cookie,那么这个方法就会重写url,当然这个url是指向本站的url
本人是菜鸟一枚,当做学习笔记写博客。谢谢各路大咖驻足审阅