Cookie和Session
Cookie 饼干
- Cookie翻译过来是饼干的意思
- Cookie是服务器通知客户端保存键值对的一种技术
- 客户端有了Cookie后,每次请求都发送给服务器
- 每个Cookie的大小不能超过4kb
- Cookie中某些特殊字符不能存在
- 空格,逗号,等于号,双引号,斜杆等特殊字符
- Cookie的个数限制:不同浏览器有不同的标准:20~50个
- Cookie的设置只能一个一个设置,不能批量设置
package com.jx.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class CookieServlet extends BaseServlet{
protected void createCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// System.out.println("hhh");
//1.创建Cookie对象
Cookie cookie=new Cookie("key1","value1");
//2.通知客户端保存Cookie
resp.addCookie(cookie);
//1.创建Cookie对象
Cookie cookie1=new Cookie("key2","value2");
//2.通知客户端保存Cookie
resp.addCookie(cookie1);
resp.getWriter().write("Cookie创建成功");
}
}
服务器如何获取Cookie
- 服务器获取客户端的Cookie只需要一行代码,req.getCookies():Cookie[]
protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie[] cookies=req.getCookies();
// Cookie iwantCookie=null;
Cookie iwantCookie= CookieUtils.findCookie("key1",cookies);
//
// for (Cookie cookie : cookies) {
// //getName方法返回Cookie的key
// //getValue返回Cookie的value值
// resp.getWriter().write("Cookie["+cookie.getName()+"="+cookie.getValue()+"]<br/>");
// if("key2".equals(cookie.getName())){
// iwantCookie=cookie;
// break;
// }
// }
if(iwantCookie!=null){
resp.getWriter().write("找到了需要的Cookie");
}
}
package com.jx.util;
import javax.servlet.http.Cookie;
public class CookieUtils {
/**
* 查找指定的Cookie对象
* @param name
* @param cookies
* @return
*/
public static Cookie findCookie(String name,Cookie[] cookies){
if(name==null||cookies==null||cookies.length==0){
return null;
}
for (Cookie cookie : cookies) {
if(name.equals(cookie.getName())){
return cookie;
}
}
return null;
}
}
Cookie值的修改
方案一
- 先创建一个要修改的同名的Cookie对象
- 在构造器,同时赋予新的Cookie值
- 调用response.addCookie(Cookie)
protected void updateCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie cookie=new Cookie("key1","newValue1");
resp.addCookie(cookie);
resp.getWriter().write("key1的Cookie已经修改好了");
}
方案二
- 先查找到需要修改的Cookie对象
- 调用setValue方法赋予新的Cookie值
- 调用response.addCookie()通知客户端保存修改
protected void updateCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// Cookie cookie=new Cookie("key1","newValue1");
// resp.addCookie(cookie);
// resp.getWriter().write("key1的Cookie已经修改好了");
Cookie cookie=CookieUtils.findCookie("key2",req.getCookies());
if(cookie!=null){
cookie.setValue("newVaule2");
resp.addCookie(cookie);
}
}
Cookie生命控制
- Cookie的生命控制指的是如何管理Cookie什么时候被销毁(删除)
setMaxAge()
- 正数,表示在指定描述后过期
- 负数,表示浏览器一关,Cookie就会删除
- 零,表示马上删除Cookie
protected void defaultLife(HttpServletRequest req, HttpServletResponse resp){
Cookie cookie=new Cookie("defaultLife","defaultLife");
cookie.setMaxAge(-1);//关闭浏览器销毁
resp.addCookie(cookie);
}
protected void deleteNow(HttpServletRequest req, HttpServletResponse resp) throws IOException {
Cookie cookie=CookieUtils.findCookie("key2",req.getCookies());
if(cookie!=null){
//调用setMaxAge(0)
cookie.setMaxAge(0);//表示马上删除,不需要等待浏览器关闭
//调用pesp.addCookie();
resp.addCookie(cookie);
resp.getWriter().write("key2的cookie已经被删除");
}
}
protected void life3600(HttpServletRequest req, HttpServletResponse resp) throws IOException{
Cookie cookie=new Cookie("life3600","life3600");
cookie.setMaxAge(60*60);//关闭浏览器销毁
resp.addCookie(cookie);
resp.getWriter().write("已经创建存活1小时的cookie");
}
Cookie有效路径Path的设置
-
Cookie的Path属性可以有效的过滤哪些Cookie可以发送给服务器,哪些不发
-
path属性是通过请求的地址来进行有效的过滤
CookieA path=/工程路径
CookieB path=/工程路径/abc
请求地址如下:
http://ip:port/工程路径/a.html
CookieA 发送
CookieB 不发送
http://ip:port/工程路径/abc/a.html
CookieA 发送
CookieB 发送
protected void testPath(HttpServletRequest req, HttpServletResponse resp) throws IOException {
Cookie cookie=new Cookie("path1","path1");
//getContextPath() 得到工程路径
cookie.setPath(req.getContextPath()+"/abc");
resp.addCookie(cookie);
resp.getWriter().write("创建了一个带有Path路径的Cookie");
}
Cookie练习—免输入用户名登录
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// super.doGet(req, resp);
String username=req.getParameter("username");
String password=req.getParameter("password");
if("wzg168".equals(username)&&"123456".equals(password)){
Cookie cookie=new Cookie("username",username);
cookie.setMaxAge(60*60*24*7);//设置一周有效
resp.addCookie(cookie);
System.out.println("登录成功");
}else{
System.out.println("登录失败");
}
}
}
Session
Session会话
- Session是一个接口(HttpSession)
- Session就是会话,用来维护一个客户端和服务器之间关联的一种技术
- 每个客户端都有自己的一个Session会话
- Session会话中,我们经常用来保存用户登录之后的信息
创建Session和获取(id号,是否为新)
-
创建和获取Session,它们的api是一样的
-
request.getSession()
- 第一次调用是:创建Session会话
- 之后调用都是:获取前面创好的Session会话对象
-
**isNew()**判断到底是不是刚创建出来的(新的)
- true 表示刚创建
- false 表示获取之前创建
-
每个会话都有自己的一个身份证号,也就是id值,这个id是唯一的
-
getId()得到Session会话的id值
protected void createOrGetSession(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// super.doGet(req, resp);
//创建和获取Session会话对象
HttpSession session= req.getSession();
//判断当前Session会话,是否是新创建出来的
boolean isNew=session.isNew();
//获取Session会话的唯一标识id
String id=session.getId();
resp.getWriter().write("得到的Session,它的id是:"+id+"<br />");
resp.getWriter().write("这个Session是否是新创建的:"+isNew+"<br />");
}
Session域数据的存取
/**
* 往Session域中保存数据
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void setAttribute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getSession().setAttribute("key1","value1");
resp.getWriter().write("已经往Session中保存了数据");
}
/**
* 获取Session域中的数据
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
protected void getAttribute(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// req.setAttribute("key1","value1");
Object attribute=req.getSession().getAttribute("key1");
// System.out.println(attribute);
resp.getWriter().write("从Session中获取出key1的数据:"+attribute);
}
Session生命周期控制
- public void setMaxInactiveInterval(int interval) 设置Session的超时时间(以秒为单位),超过指定的时长,Session就会被销毁
- 值为正数的时候,设定Session的超时时长
- 负数表示永不超时(极少使用)
- public int getMaxIncativeInterval() 获取Session的超时时间
- Session默认的超时时长为30min
protected void defaultLife(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
int maxInactiveInterval=req.getSession().getMaxInactiveInterval();
resp.getWriter().write("Session的默认超时时长:"+maxInactiveInterval+"秒");
}
- 修改默认的超时时长,可以修改Web工程所有Session的默认时长
<!-- 表示当前Web工程,创建出来的所有Session默认是20分钟超时时长 -->
<session-config>
<session-timeout>20</session-timeout>
</session-config>
- 修改个别Session的超时时长
protected void life3(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取Session对象
HttpSession session=req.getSession();
//设置当前Session 3 秒后超时
session.setMaxInactiveInterval(3);
resp.getWriter().write("当前Session已经设置为3秒后超时");
}
Session的超时指的是,客户端两次请求的最大间隔时长
浏览器和Session之间关联的技术内幕
Session技术,底层其实是基于Cookie技术来实现的