Cookie、Session
会话
会话:用户打开一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程可以称之为会话;
有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学,曾经来过,称之为有状态会话;
保存会话的两种技术
cookie
- 客户端技术(响应、请求)
session
- 服务器技术,利用这个技术,可以保存用户的会话信息? 我们可以把信息或者数据放在Session中!
Cookie
cookie:一般会保存在本地的 用户目录下 appdata;
一个网站cookie是否存在上限!聊聊细节问题
- 一个Cookie只能保存一个信息;
- 一个web站点可以给浏览器发送多个cookie,最多存放20个cookie;
- Cookie大小有限制4kb;
- 300个cookie浏览器上限
删除Cookie;
- 不设置有效期,关闭浏览器,自动失效;(默认)
- 设置有效期时间为 0 ;
注意
- cookie默认有效期是在浏览器关闭后失效,如果设置了有效期就在过期后失效
public class CookieDemo1 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//服务器告诉你你来的时间,把时间封装成一个信件,下次来的时候带着
//编码解决中文乱码
resp.setCharacterEncoding("utf-8");
req.setCharacterEncoding("utf-8");
//响应
PrintWriter out = resp.getWriter();
//Cookie ,服务端从客户端获取
Cookie[] cookies = req.getCookies();//返回数组,说明可能存在多个
//判断Cookie是否存在
if(cookies!=null){
//如果存在怎么办
out.write("When was your last visit: ");
for(int i = 0; i <cookies.length ; i++){
Cookie cookie = cookies[i];
//或缺Cookie的名字
if(cookie.getName().equals("LastLoginTime")){
//获取cookie中的值
long LastLoginTime = Long.parseLong(cookie.getValue());
Date date = new Date(LastLoginTime);
out.write(date.toLocaleString());
}
}
}else{
System.out.println("This is your first visit");
}
//服务器给客户端响应一个Cookie
Cookie cookie = new Cookie("LastLoginTime", System.currentTimeMillis()+"");
//给cookie设置有效期为一天
cookie.setMaxAge(24*60*60);
resp.addCookie(cookie);
}
Cookie[] cookie = req.getCookies();//获得cookie
cookie.getName();//获得cookie中的key
cookie.getValve();//获得cookie中的value
new Cookie("LastLoginTime", System.currentTimeMillis()+"");//新建cookie
cookie.setMaxAge(24*60*60); //给cookie设置有效期为一天
resp.addCookie(cookie);//添加一个cookie
编码与解码,防止乱码
@WebServlet("/c3")
public class CookieDemo2 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException{
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
for(Cookie cookie : req.getCookies()){
if(cookie.getName().equals("name")){
//URLDecoder解码
out.write(URLDecoder.decode(cookie.getValue(),"utf-8"));
}
}
//URLEncoder编码
Cookie cookie =new Cookie("name",URLEncoder.encode("筱语","utf-8"));
resp.addCookie(cookie);}
}
<!--web.xml注册-->
<servlet>
<servlet-name>CookieDemo1</servlet-name>
<servlet-class>com.kuang.servlet.CookieDemo1</servlet-class>
</servlet>
<!-- servlet请求路径-->
<servlet-mapping>
<servlet-name>CookieDemo1</servlet-name>
<url-pattern>/c1</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>CookieDemo2</servlet-name>
<servlet-class>com.kuang.servlet.CookieDemo2</servlet-class>
</servlet>
<!-- servlet请求路径-->
<servlet-mapping>
<servlet-name>CookieDemo2</servlet-name>
<url-pattern>/c2</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>CookieDemo3</servlet-name>
<servlet-class>com.kuang.servlet.CookieDemo3</servlet-class>
</servlet>
<!-- servlet请求路径-->
<servlet-mapping>
<servlet-name>CookieDemo3</servlet-name>
<url-pattern>/c3</url-pattern>
</servlet-mapping>
Session(重点)
什么是session
服务器会给每一个用户(浏览器)创建一个session对象
一个session独占一个浏览器,主要浏览器没有关闭,这个session就存在
用户登录后,整个网站它都可以访问——>保存用户的信息,保存购物车的信息。
给session中存用户信息
public class Servlet_09_Session extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html; charset=UTF-8");
//获得Session
HttpSession session = req.getSession();
//给Session存东西
//session.setAttribute("name","小狗");
session.setAttribute("name",new Person(18,"小红",123456789));
//获取Session的id
String id = session.getId();
System.out.println(id);
//判断Session是不是新创建的
boolean aNew = session.isNew();
if(aNew){
resp.getWriter().println("session创建成功! session id 为: "+id);
}else{
resp.getWriter().println("session已经创建了id 为: "+id);
}
//session在创建的时候做了啥
//Cookie cookie = new Cookie("SESSIONID", id);
//resp.addCookie(cookie);
}
@Override
protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
获取session中存储的用户信息
public class Servlet_09_SessionGet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决编码问题
resp.setCharacterEncoding("utf8");
req.setCharacterEncoding("utf8");
resp.setContentType("text/html; charset=UTF-8");
//的到session
HttpSession session = req.getSession();
Person person = (Person) session.getAttribute("name");
System.out.println(person.toString());
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
每次新打开一个浏览器访问地址,都会新建一个session会话,也会向客户端存储一个值为sessionId的cookie。
手动注销session
public class Servlet_10_SessionRemove extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
session.removeAttribute("name");
session.invalidate();//注销
}
设置session的失效时间,在web.xml中
<!--设置Session默认的失效时间-->
<session-config>
<!--15分钟后Session自动失效,以分钟为单位-->
<session-timeout>15</session-timeout>
</session-config>
7天免登录案例实现
思路:session在一次会话后就会结束,所以可以通过servletContext来存储当前的session,以sessionId为key,session对象为值,然后将sessionId存在客户端的cookie中,每次获取用户信息先去cookie中查找是否有这个id,然后通过该id获取servletContext中的session对象实现。
登录接口,将session存到ServletContext中
@WebServlet("/ss1")
public class SessionAn extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException{
resp.setContentType("text/html;charset=utf-8");
HttpSession session = req.getSession();
session.setAttribute("name","小腿");
String sessionId = session.getId();
Cookie cookie =new Cookie("session",sessionId);
cookie.setMaxAge(Integer.MAX_VALUE);
resp.addCookie(cookie);//存session对象
this.getServletContext().setAttribute(sessionId,session);
resp.getWriter().write("登录成功!");} }
获取用户信息接口
@WebServlet("/ss2")
public class SessionAn2 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException{
resp.setContentType("text/html;charset=utf-8");
String sId ="";
for(Cookie cookie : req.getCookies()){
if(cookie.getName().equals("session")){
sId = cookie.getValue();
}
}
HttpSession session =(HttpSession)this.getServletContext().getAttribute(sId);
String name =(String)session.getAttribute("name");
resp.getWriter().write("欢迎你,"+name);
}
}
先访问ss1接口,设置用户信息到session中,然后访问ss2接口就可以拿到用户信息了。将cookie过期时间设置为7天即可。当关闭浏览器后,下次直接访问ss2接口就能拿到用户信息,相当于不用再通过ss1接口登录了。
注意:每次访问网站都会生成一个JsessionId在cookie中,而且会是不同的值。
session与cookie异同
COOKIE | SESSION |
---|---|
存在客户端中,不安全 | 存在服务端中,比较安全 |
只支持存字符串数据 | 支持任意数据类型 |
单个cookie存的数据大小不能超过4k | 可存储数据远高于Cookie |
使用场景:
- 保存一个登录用户的信息
- 购物车信息
- 在整个网站中经常会使用的数据,我们将他保存在Session中