一.HttpSession概述
- HttpSession是由JavaWeb提供的,用来会话跟踪的类,session是服务器端对象,保存在服务器端
- HttpSession是Servlet三大域对象之一
- request-有几个请求就有几个request对象
- session-从浏览器打开到关闭前都是一个session对象
- application(ServletContext)
- 所以它也有setAttribute(),getAttribute(),removeAttribute()方法
- HttpSession底层依赖Cookie 或是URL重写
二.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)
简而言之,一个用户打开一个浏览器,只可能有一个session对象,想拥有新的session对象就关闭浏览器重新打开浏览器,当然你也可以打开其他的浏览器,不过此时从意义上能看着是创建了一个“新的用户”,所以不存在同时存在两个session的情况
三.演示在session会话中的多次请求中共享数据
此时你这样也会报错,因为session是jsp的九大内置对象之一,在jsp中本身就存在了变量名为session的对象了,此时就相当于重复定义了变量名,所以就会报错
a.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>保存session</h1>
<%
session.setAttribute("AAA","aaa");
%>
</body>
</html>
b.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>获取session</h1>
<%
String str=(String)session.getAttribute("AAA");
out.print(str);
%>
</body>
</html>
打开ie浏览器
访问a.jsp效果如下
在本窗口中改地址访问b.jsp效果如下
再不关闭本窗口的情况下,在打开一个新的ie浏览器访问b.jsp效果如下
为什么能够获取得到session呢?因为session是靠cookie来实现的,准确来说是靠cookie总JSESSIONID实现的
尽然是靠cookie实现的,因为cookie是无法跨浏览器的,所以如果你用的是ie浏览器以往的浏览器访问b.jsp,效果就肯定会如下一样,无法获取到session
注意:ie浏览器有个新建窗口,点击这个选项也会等同于打开了另外的浏览器,即在本例中无法获取到session对象
四.保存用户登录信息
看图大致我们就知道怎么写代码了
首先是三个jsp
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
String name="";
Cookie [] cookies=request.getCookies();
for(Cookie c:cookies){//获取cookie就是为了保留用户名,第二次登录时不用输入用户名了
if(c.getName().equals("name")){
name=c.getValue();
}
}
%>
<h1>${msg}</h1>
<form action="/javaweb6/LoginServlet" method="post">
用户名:<input type="text" name="username" value="<%=name%>"><br/>
密码:<input type="password" name="pwd"><br/>
<input type="submit" value="提交"><br/>
</form>
</body>
</html>
succ1.jsp,succ2.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
String uname=(String)session.getAttribute("username");
if(uname==null){
request.setAttribute("msg","请重新登录!!!");
request.getRequestDispatcher("/session2/login.jsp").forward(request, response);
}
%>
<h1>欢迎<%=uname%>到达succ1工厂查看工作</h1>
</body>
</html>
紧接着一个Servlet
LoginServlet
public class LoginServlet extends HttpServlet {
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//POST请求编码处理
request.setCharacterEncoding("UTF-8");
//获取表单信息
String username=request.getParameter("username");
String password=request.getParameter("pwd");
if(!username.contains("st")) {//用户名没有含有st就登录成功,否则失败
HttpSession session=request.getSession();//Servlet中session对象要自己创建
Cookie cookie1=new Cookie("name",username);
cookie1.setMaxAge(60*60*24);//设置cookie的生存时间24小时
response.addCookie(cookie1);
session.setAttribute("username",username);
session.setAttribute("pwd",password);
response.sendRedirect("/javaweb6/session2/succ1.jsp");//重定向
}else {
request.setAttribute("msg","密码或用户名错误!!!");//保存错误信息
request.getRequestDispatcher("/session2/login.jsp").forward(request, response);;//转发
}
}
}
五.HttpSession原理
1.request.getSession()方法
- 获取Cookie中的sessionId
- 如果sessionId不存在,创建session,把session保存起来,把新创建的sessionId保存到Cookie中
- 如果sessionId存在,通过sessionId查找session对象,如果没有查找到,创建session,把session保存起来,把新创建的sessionId保存到Cookie中
- 如果sessionId存在,通过sessionId查找到了session对象,那么就不会再创建session对象了
- 最后,返回session
如果创建了新的session,浏览器会得到一个包含了sessionId的Cookie,这个Cookie的生命为-1,即只在浏览器内存中存在,如果不关闭浏览器,那么Cookie就一直存在
下次请求时,再次执行request.getSession()方法时,因为可以通过Cookie中的sessionId找到session对象,所以与上一次请求使用的是用一个session对象
2.例子
- 服务器不会马上给你创建session,在第一次获取session时,才会创建! request.getSession();
public class AServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
}
}
访问这个AServlet显示并不存在
当然如果你访问jsp的话,效果就不同了
在jsp中,session可是内置对象之一,本身就给你创建好了得,可以直接使用
当然如果你在AServlet中加上一行代码就不一样了
HttpSession session=request.getSession();
request.getSession(false),request.getSession(true),request.getSession(),后两个方法效果相同
第一个方法:如果session缓存中(如果cookie不存在),不存在session,那么返回null,而不会创建session对象
第二,三方法绝对会创建出session对象,第一个并不行
因为二,三先是获取有没有原来的,没有原来的就创建一个新的,所以必然会创建出session对象
六.HttpSession其他方法
1.获取sessionId
String getId()
可以看出sessionId是32位长度并且16进制的一串数字,平常我们工作中会经常让我们自己生成这类数字,我们来看看怎么实现?
@Test
public void fun1() {
String string1=UUID.randomUUID().toString();//生成带有-的32位16进制数字
System.out.println(string1);
String string2=string1.replace("-","");//替换掉,不过此时还要把小写转换成大写
System.out.println(string2.toUpperCase());
}
下面我们就可以把这个写成一个工具类,以后有用!!!
public class CommonUtils {
public static String getuuid() {
return UUID.randomUUID().toString().replace("-","").toUpperCase();
}
}
2.获取session可以的最大不活动时间
int getMaxInactiveInterval()//默认为30分钟
3.让session失效
void invalidate()//调用这个方法会被session失效
4.查看session是否为新。
boolean isNew()//当客户端第一次请求时,服务器为客户端创建session,但这时服务器还没有响应客户端,也就是还没有把sessionId响应给客户端时,这时session的状态为新。
request.getSession.isNew可以拿来查看我们是创建session还是在获取session
5.配置session中的最大不活动时间
在web.xml文件中配置如下信息
<session-config>
<session-timeout>30</session-timeout>//单位是分钟,默认是30分钟
</session-config>
七.URL重写
- 就是把所有的页面中的路径,都使用response.encodeURL()处理一下
- session依赖Cookie,目的是让客户端发出请求时归还sessionId,这样才能找到对应的session,如果客户端禁用了Cookie,那么无法得到sessionId,那么session也就无用了,也可以使用URL重写来替代Cookie
- 让网站的所有超链接,表单中都添加一个特殊的请求参数,即sessionId,这样服务器可以通过获取请求参数得到sessionId,从而找到session对象
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="/javaweb6/AServlet?JSESSIONID=<%=session.getId()%>">请点击这里</a>
<a href="/javaweb6/AServlet?JSESSIONID=<%=session.getId()%>">请点击这里</a>
<a href="/javaweb6/AServlet?JSESSIONID=<%=session.getId()%>">请点击这里</a>
</body>
</html>
不过这样写并不好,我们都是通过getSession来获取session的,所以我们应该把?改成;
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="/javaweb6/AServlet;JSESSIONID=<%=session.getId()%>">请点击这里</a>
<a href="/javaweb6/AServlet;JSESSIONID=<%=session.getId()%>">请点击这里</a>
<a href="/javaweb6/AServlet;JSESSIONID=<%=session.getId()%>">请点击这里</a>
</body>
</html>
不过这种方式是不支持Cookie的时候再写的,当然我们有更智能的方法,就是URL重写
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="/javaweb6/AServlet;JSESSIONID=<%=session.getId()%>">请点击这里</a>
<a href="/javaweb6/AServlet;JSESSIONID=<%=session.getId()%>">请点击这里</a>
<a href="/javaweb6/AServlet;JSESSIONID=<%=session.getId()%>">请点击这里</a>
<%
//它会查看cookie是否存在
//如果不存在 在指定的url后添加jsessionid参数
//如果存在 它就不会再url后添加任何东西
out.print(response.encodeURL("/javaweb6/AServlet"));
%>
</body>
</html>
首次访问页面的时候,并没有响应出jsessionid参数,所以出现下面这种情况
再次访问,因为jsessionid存在,并响应出来,所以就不会在url后添加任何东西了
END!!!!!!!!!