JavaWeb从头再来系列之HttpSession基本知识介绍

目录:
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>

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值