会话跟踪:一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于用一个浏览器,以便于在同一次会话的多次请求间共享数据。
服务器是不知道这个请求是不是同一浏览器的,因为http协议是无状态的,每次浏览器向服务器请求时,服务器都会将该请求视为新的请求,因此需要会话跟踪技术实现会话内数据共享。
实现方式:
1.客户端会话跟踪技术:Cookie
2.服务端会话跟踪技术:Session
Cookie:客户端会话技术,将数据保存到客户端,以后每次请求都携带Cookie数据进行访问。
比如浏览器发送请求访问服务器A,服务器A会创建一个Cookie对象数据,服务器A作出响应,把Cookie发给客户端浏览器,浏览器保存cookie到浏览器内存,浏览器再同一次会话中再次请求服务器B,这时浏览器会携带Cookie访问服务器B,服务器B就会拿到cookie里面的数据。
作为服务端开发人员,咱不关心客户端浏览器,咱只关心服务器怎么发送cookie和获取cookie。
@WebServlet("/aCookie")
public class CookieServletA extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie cookie = new Cookie("username", "lisisi123");
resp.addCookie(cookie);
}
}
@WebServlet("/aCookie")
代替web.xml配置
cookie
com.weiwei.cookiedemo.Servlet.CookieServletA
cookie
/ aCookie
@WebServlet("/bCookie")
public class CookieServletB extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取cookie
Cookie[] cookies = req.getCookies();
for (Cookie cookie:cookies) {
String cookieName = cookie.getName();
String cookieValue = cookie.getValue();
System.out.println(cookieName+"\t"+cookieValue);//username lisisi123
}
}
}
Cookie实现是基于HTTP协议的
响应头:set—cookie
请求头:cookie
默认情况下,Cookie存储在浏览器内存中,当浏览器关闭,内存释放,则Cookie被销毁。
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取cookie
Cookie[] cookies = req.getCookies();
if(cookies!=null&&cookies.length>0){
for (Cookie cookie:cookies) {
String cookieName = cookie.getName();
String cookieValue = cookie.getValue();
System.out.println(cookieName+"\t"+cookieValue);//username lisisi123
}
}else {
System.out.println("无cookie");
}
}
}
setMaxAge(int seconds):设置Cookie存活时间
(1)正数:将Cookie写入浏览器所在的电脑硬盘,持久化存储,到期自动删除
(2)负数:默认值,Cookie存储在浏览器内存中,当浏览器关闭,内存释放,则Cookie被销毁。
(3)零:删除对应Cookie
Cookie不能直接存储中文,即value值的地方不能写中文,不然会报错。
如果需要存储,则需要进行转码:URL编码
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String value="张三";
//URL编码
value = URLEncoder.encode(value, "utf-8");
Cookie cookie = new Cookie("username", value);
System.out.println("存储数据===="+value);
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取cookie
Cookie[] cookies = req.getCookies();
if(cookies!=null&&cookies.length>0){
for (Cookie cookie:cookies) {
String cookieName = cookie.getName();
String cookieValue = cookie.getValue();
System.out.println(cookieName+"\t"+cookieValue);
//URL解码
cookieValue = URLDecoder.decode(cookieValue, "UTF-8");
System.out.println("解码后===="+cookieValue);
}
}else {
System.out.println("无cookie");
}
}
存储数据====%E5%BC%A0%E4%B8%89
JSESSIONID BD05A996C36BDA5FC149627DA4A1E4D8
解码后====BD05A996C36BDA5FC149627DA4A1E4D8
username %E5%BC%A0%E4%B8%89
解码后====张三
HttpSession session = req.getSession();
if ("zhangsan".equals(username) && "123456".equals(password)){
//跳转到成功页面
//利用session对象的方法传递数据
session.setAttribute("username",username);
resp.sendRedirect("success");//sendRedirect不能传递数据
}else{
req.getRequestDispatcher("/login").forward(req,resp);
}
}
参考Servlet(4)
重新打开浏览器访问,就不是同一个session了
3.Cookie和Session区别