目录:
1.HttpSession的概述
2.HttpSession的方法
3.服务器什么时候创建Session
4.HttpSession的原理
5.Session和cookie的区别
6.URL重写!
7.HttpSession登录案例
一:HttpSession的概述
HttpSession是由JavaWeb提供的,用来会话跟踪的类。session是服务器端对象,保存在服务器端!!!
他是域对象之一,所以有setAttribute(), getAttribute(), removeAtrribute();
HttpSession底层依赖Cookie 或者 URL重写
会话:就是从用户打开浏览器,中间可以有N个请求和响应,然后关闭浏览器,就是一个会话
只要用户没有关闭浏览器,session就一直存在(可以理解成对话!), 一个用户对应一个会话!
二:HttpSession的方法
getSession() 和getSession(true) 等价:都是如果Session缓存中存在,那么直接返回,如果不存在创建之后再返回!!!
request.getSession(false):如果Session缓存中不存在Session,那么会返回null,不会去创建Session对象!
String getId():获取sessionId;UUID.randomUUID().toString().replace("-", "").toUpperCase()
int getMaxInactiveInterval():获取session可以的最大不活动时间(秒),默认为30分钟。当session在30分钟内没有使用,那么Tomcat会在session池中移除这个session;
注:还有一个setMaxInactiveInterval()
void invalidate():让session失效!调用这个方法会被session失效,当session失效后,客户端再次请求,服务器会给客户端创建一个新的session,并在响应中给客户端新session的sessionId;
boolean isNew():查看session是否为新。当客户端第一次请求时,服务器为客户端创建session,但这时服务器还没有响应客户端,也就是还没有把sessionId响应给客户端时,这时session的状态为新。
注:这个方法的作用,是可以判断request.getSession(); 是第一次创建的,还是返回的
web.xml中配置session的最大不活动时间
<session-config>
<session-timeout>30</session-timeout>
</session-config>
三:服务器什么时候创建Session??
服务器不会马上给你创建Session,在第一次获取Session的时候才会创建!!request.getSession()
request.getSession()的原理!!!
当你使用request.getSession() 时,他会做如下事情!
1.从cookie中获取JSESSIONID,或者请求参数中(jsessionid是一个Cookie,要不然怎么说Session底层依赖Cookie呢)
2.如果Jsessionid不存在,那服务器就会创建JsessionID,创建Session,然后保存到Session缓存类似:Map<Jseessionid,Sesesion>!这么一种结构,新创建的 seesionId会保存一份到Cookie中,让它响应给客户端
3.如果JsessionId存在,但根据Jsessionid 获取不到Session,也会重新创建jseessionid,创建Session,保存在Session
缓存,将新创建的jsessionid保存在cookie中,让它响应给客户端!
4.如果JsessionId存在,并且通过 JsessionId找到了 Session,那么就直接返回这个Session!!!
注:这个名为Jsessionid的cookie默认生命为-1,也就是关闭浏览器就死了
伪代码:只是便于自己理解!
//类似Session缓存的这种结构
Map<Jsessionid,Session> map = new HashMap<>(Jsessionid,Session);
获取cookie的JsessionId
if(jSessionId == null){ -->如果你卡号丢了
创建Jsessionid --> 创建卡号
创建Session --> 创建账号
保存Session: map.put(Jsessionid,Session);
Cookie c = new Cookie("Jsessionid",Jsessionid);//把卡号给你带回去!
resp.addCookie(c);
return session;
}else{
Seesion session = map.get(Jsessionid);
if(session == null){
创建Jsessionid
创建Session
保存Session: map.put(Jsessionid,Session);
Cookie c = new Cookie("Jsessionid",Jsessionid);
resp.addCookie(c);
return session;
}else{
return session;
}
}
由上面我们可以知道,如果request.getSession创建了一个Session,那么会顺带创建一个名为JsessionId的cookie,让它返回给
客户端,那么这是真的吗?,我们来实验一下!
BServlet:
@WebServlet("/BServlet")
public class BServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
response.getWriter().println("请查看是否有JSESSIONID这个cookie");
}
}
我们请求一下BServlet
注:因为它并没有使用request.getSession();
我们再来随便访问一个jsp! 尽管里面没有任何内容!
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
</body>
</html>
我们请求一下test.jsp
发现居然返回了 JSESSIONID, 但我在代码中没有写request.getSession()代码啊,怎么会返回呢?
因为seesion是jsp的内置对象,我们记不记得将 jsp的”真身”,jsp先会转译成.java (Servlet),在这个里面
其实已经创建的HttpSession !!!
四:Session的原理跟去银行办卡差不多!!
第一次来办卡,银行给了我卡号,然后在后台Map<卡号,账号>
第二次来我就会带着卡来,然后匹配到了
假如我第二次卡丢了,银行就会重新新创建一个卡号 Map<卡号,账号> 然后把卡号给我
五:Session和Cookie的区别
Session是创建在服务器端,保存在服务器端
Session和Http无关
Cookie是创建在服务器端,保存在客户端!
Cookie是和Http有关的,请求头:Cookie 响应头:Set-Cookie
六:URL重写!!(就是用来模拟cookie的)
假如客户端浏览器阻止第三方的cookie,就是阻止cookie的响应头,那么jsessionID就带不回去了!
那怎么办,这时候就需要URL重写!你不是阻止我的响应头,那么直接动态放到超链接中!
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!--客户端路径: 以/开头是相对于主机 -->
<a href="/day_09/BServlet;JSESSIONID=<%=session.getId()%>">点击这里</a><br/>
<a href="/day_09/BServlet;JSESSIONID=<%=session.getId()%>">点击这里</a><br/>
<a href="/day_09/BServlet;JSESSIONID=<%=session.getId()%>">点击这里</a><br/>
</body>
</html>
注意:路径之间是分号;不是?号!!!
客户端访问我这个jsp的时候,当这个jsp转译成.java的时候就创建了HttpSession,这时我获取JsessionId,把它放在超链接上
返回给客户端,那么当客户端点击超链接的时候,我要获取到了Jsessionid !!!, 所以达到了目的
问题:那么我怎么知道客户端禁不禁用cookie, 如果不禁用cookie,那么我这个超链接后面,不是没有必要带JsessionID,
解决:使用response.encodeURL();
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!--客户端路径: 以/开头是相对于主机 -->
<a href="/day_09/BServlet;JSESSIONID=<%=session.getId()%>">点击这里</a><br/>
<a href="/day_09/BServlet;JSESSIONID=<%=session.getId()%>">点击这里</a><br/>
<a href="/day_09/BServlet;JSESSIONID=<%=session.getId()%>">点击这里</a><br/>
<%
//它会查看cookie是否存在,如果不存在会加上JessionId,如果存在,则不会加
out.println(response.encodeURL("/day_09/BServlet"));
%>
</body>
</html>
总结:就是把所有的页面中的路径,都使用response.encodeURL("..")处理一下!
六:Seesion的案例 (保存用户登录信息)
Login.jsp代码
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<!--有头的作用,但是是体! -->
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
String uname = "";
Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {
if(cookie != null) {
if(cookie.getName().equals("u")) {
uname = cookie.getValue();
}
}
}
%>
<h1>登录页面</h1>
<%
String message = "";
String msg = (String)request.getAttribute("error");
if(msg != null){
message = msg;
}
%>
<font color="red"><b><%=message%></b></font>
<form action="/day_09/LoginServlet" method="post">
username: <input type="text" name="username" value="<%=uname%>"> <br/>
password: <input type="password" name="pwd" value=""> <br/>
<input type="submit" value="提交">
</form>
</body>
</html>
LoginServlet代码
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
String name = req.getParameter("username");
String pwd = req.getParameter("pwd");
HttpSession session = req.getSession();
if(name.equals("wzj") && pwd.equals("12345")) {
//显示用户名
Cookie c = new Cookie("u", "wzj");
c.setMaxAge(60*60);//存活在硬盘1h
resp.addCookie(c);
session.setAttribute("user", "wzj");
//客户端路径: 带/相对于主机
resp.sendRedirect("/day_09/success.jsp");
}else {
req.setAttribute("error", "账号或密码失败!");
//服务器路径:带/相对于项目
req.getRequestDispatcher("/login.jsp").forward(req, resp);
}
}
}
success.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
String user = (String)request.getSession().getAttribute("user");
if(user == null){
request.setAttribute("error", "您还没有登录");
request.getRequestDispatcher("/login.jsp").forward(request, response);
return;
}
%>
欢迎: <%=user %> 登录成功!
</body>
</html>