1、会话:什么叫会话?由同一个客户端,向同一个服务器系统发起的1---N次请求。
2、会话跟踪:见名知义,用来跟踪用户的整个会话;由于HTTP协议天生是无状态的,客户端提交数据完毕后,就会失去服务器与客户端的连接,当再次请求时,需要建立新的连接,因此无法再连接上建立会话跟踪。 另外,在基于http协议与服务器交互过程中,服务器无法主动记录用户的状态信息,进而也无法跟踪用户与服务器的会话;为了解决这一问题,cookie和session相关技术相继诞生。
cookie技术:服务器根据客户端保存的信息,确定用户的身份。
session技术:服务器根据服务器保存的信息,确定用户的身份。
3、Cookie技术(cookie类位于javax.servlet.http.*)
3.1)cookie是由服务器颁发给客户端的一小段文本信息,这段文本信息存储在客户端的浏览器上。
3.2)Cookie原理:(Cookie的原理相当于一个人的身份证)
当客户第一次发送请求的时候,服务器会给颁发给客户端一个标记(信息存放在响应头上,返回客户端并记录在浏览器上),当客户端再次向该服务发起请求时(请求头携带信息),会把标记发给服务器,此时服务器就能根据请求头分析用户特有的信息,从而动态生成客户特有的网站信息。(应用实例:比如记住密码)
3.3)(了解)cookie存在有两种方式:如果说cookie生存时间是一个会话期间,那么浏览器将会把cookie保存在一个内存中,关闭浏览器时, 此cookie被销毁。另一种方式,将cookie存放在硬盘上,关闭浏览器,也不会被销毁,当客户端再次访问同一个网站的时候,浏览器就会寻找响应的cookie,并将此信息发送到服务器端。
3.4)如果查看一个网站的cookie的话,只需在地址栏上输入javascript:alter(document. cookie);但是一般都会被做加密处理。
3.5)cookie是有客户端浏览器自动管理,所有cookie具有不可跨域性(有cookie的隐性安全机制决定)(浏览器做特殊处理外).
3.6) cookie的使用:
创建一个Cookie: Cookie cookie = new Cookie(Stirng name,Object value);
设置Cookie到客户端浏览器:response.addCookie(cookie);
获取客户端浏览的cookie:Cookie cookies[] = request,getCookies( );
其余常用方法:getName(),getValue(),setPath(url),setMaxAge( )
3.7) cookie的生命周期:默认情况下,cookie的存活时间是与浏览器绑定。关闭浏览器销毁。
但是可以通过手动设置cookie的存活时间 :cookie.setMaxAge(10000)单位是秒,可以使0和负数
0是删除当前cookie,负数时与当前浏览器进行绑定。(默认是-1)
3.8)cookie的缺陷:1)cookie以明文存储信息,数据不安全
2)cookie存储的信息量小,默认是4KB
3)cookie默认不支持中文。
4)cookie可以被禁用
注意:cookie功能需要浏览器的支持。
4、session技术
4.1)session技术也可以解决会话跟踪技术,较cookie较简单,session信息会存在服务器内,相对增加了服务器的存储压力。因此,出现了session的持久化技术。
4.2)session原理:
当用户第一次请求服务器创建session的时候,服务器会在创建好的session同时,将当前session的id,主动设置到客户端浏览器的cookie上保存,这个cookie是:jsessionid = sessionid(,,,,,,,,,,,,,,,,,,,,,,,,),下次请求到达服务器时,服务器主动获取客户端浏览器的jsessionid,进而可以找到对应的session对象。
session实现原理基于cookie(外来博客)
4.3)session的使用:
HttpSession session = request.getSession(true); //获取session
session.setAttribute(String name,Object value); //存值
Object value = session.getAttribute(String name); //取值
session.removeAttribute(String name); //移除一个属性
4.4)session的生命周期:
begin: 第一次调用request.getSession(true);
end: 手动销毁session.invalidate()
超时策略:服务器默认销毁(一般是20-30分钟),配置web.xml
<session-config>
<session-timeout>30</session-timeout> <!--单位分钟-->
</session-config>
可以通过setMaxInactiveInterval(Long interval) 设置超时时间(单位秒);
注意:超时时间 指 从用户最后一次请求结束开始计算。
4.5)由于session依赖于cookie,如果浏览器将cookie禁掉,session就不能使用了,那么该怎么解决这一问题?
利用URL重写:url地址重写是对客户端不支持cookie的解决方案。其原理是将session的id重新写到url地址中,服务器能够解析重写后的URL获取session的id;HttpServletResponse类提供了encodeURL(String url)实现url重写。该方法自动判断客户端是否支持cookie,如果客户端不支持cookie,会将用户session的id重写到URL中,如果支持,则不重写。重写后的URL会变为”;jsessionid=XXXXXXX“
4.6)session应用场景:强制登陆、安全退出、购物车、用户验证码
5、Cookie机制与Session机制的主要区别:
Cookie是采用客户端保持状态方案,而Session是采用服务器保持状态方案。
https://blog.csdn.net/u011145904/article/details/77745777(含义更详细的区别)
6、Cookie实现简单登陆
login.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>login</title>
</head>
<body>
<%!
String username = "";
String password="";
String currentTime="";
%>
<%
Cookie[] cookies = request.getCookies();
//判断cookies是否为空
if(cookies!=null){
//不为空,则遍历cookie
for (Cookie cookie : cookies) {
if("username".equals(cookie.getName())){
username = cookie.getValue();
}
if("password".equals(cookie.getName())){
password = cookie.getValue();
}
if("currentTime".equals(cookie.getName())){
currentTime = cookie.getValue();
}
}
}
%>
<p>username :<%=username %><br/>
password:<%=password %><br/>
您当前登陆的时间:<%=currentTime %>
</p>
<form action="/bz1/login1" method="post">
用户名:<input type="text" name="username" value=<%=username %> ><br/>
密码:<input type="text" name="password"value=<%=password %> ><br/>
<input type="submit" value="提交">
</form>
</body>
</html>
loginServlet.java
@WebServlet("/login1")
public class TestSessionServlet extends HttpServlet{
public void service(HttpServletRequest request,HttpServletResponse response) throws IOException{
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html");
String username = request.getParameter("username");
String password = request.getParameter("password");
//获取当前的时间
String currentTime = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
//创建cookie
Cookie cookie1 = new Cookie("username",username);
Cookie cookie2 = new Cookie("password",password);
Cookie cookie3 = new Cookie("currentTime",currentTime);
//设置存活时间
cookie1.setMaxAge(60*60*24*7);
cookie2.setMaxAge(60*60*24*7);
cookie3.setMaxAge(60*60*24*7);
//将cookie设置到浏览器上
response.addCookie(cookie1);
response.addCookie(cookie2);
response.addCookie(cookie3);
response.sendRedirect(request.getContextPath()+"/login.jsp");
}
}
运行截图:
7、session实现登陆和注销小案例:
login.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>login</title>
</head>
<body>
<form action="/bz1/login3" method="post">
用户名:<input type="text" name="username" value=<%=username %> ><br/>
密码:<input type="text" name="password"value=<%=password %> >
<input type="submit" value="提交">
</form>
</body>
</html>
success.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<body>
<h1>欢迎您!${user.username }</h1>
<a href="/bz1/outSalf">安全退出</a>
</body>
</html>
SessionLogin.java
package SessionServlet;
import java.io.IOException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import entity.Person;
@WebServlet("/login3")
public class SessionLogin extends HttpServlet{
public void service(HttpServletRequest request,HttpServletResponse response) throws IOException{
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html");
//假如我有一个数据里,里面有一条数据:username = 'sqc' 密码='123456'
Person p = new Person("sqc","123456");
//接收页面传过来的username 和 password
String username = request.getParameter("username");
String password = request.getParameter("password");
if(p.getUsername().equals(username) && p.getPassword().equals(password)){
/**
* request.getSession()与request.getSession(true) 如果session不存在,创建一个session
* request.getSession(false) 如果session不存在,不创建
*/
//创建一个session对象
HttpSession session = request.getSession(true);
//登陆成功后,向session中存入session对象
session.setAttribute("user", p);
response.sendRedirect(request.getContextPath()+"/success.jsp");
return ;
} else{
response.getWriter().println("用户名或密码错误!");
}
}
}
OutSalfServlet.java
package SessionServlet;
import java.io.IOException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@WebServlet("/outSalf")
public class OutSalfServlet extends HttpServlet{
public void service(HttpServletRequest request,HttpServletResponse response) throws IOException{
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html");
HttpSession session = request.getSession();
if(session==null){
response.sendRedirect(request.getContextPath()+"/login.jsp");
return ;
}
session.removeAttribute("user");
response.sendRedirect(request.getContextPath()+"/login.jsp");
}
}
运行截图:
8、判断session是否已经在服务器中创建
jsp页面代码是个登陆代码,已经省略。
package SessionServlet;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import entity.Person;
@WebServlet("/login2")
public class TestSession extends HttpServlet{
public void service(HttpServletRequest request,HttpServletResponse response) throws IOException{
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html");
String username = request.getParameter("username");
String password = request.getParameter("password");
//将数据封装成一个对象
Person p = new Person(username,password);
//创建一个session
HttpSession session = request.getSession(true);
//将数据存储到session中
session.setAttribute("person", p);
//获取session的id
String sessionId = session.getId();
if(session.isNew()){
response.getWriter().print("session创建成功!");
}else{
response.getWriter().print("服务器已存在该session,session的id:"+sessionId);
}
}
}