何为Cookie

    Cookie是服务器通知客户端保存键值对的一种技术。同时客户端保存了Cookie之后,每次请求都会发送
给服务器。每个Cookie的大小不能超过4kb。
    Cookie 是保存在客户端的。

Cookie的创建

Cookie与Session

创建代码如下:

public class CookieServlet extends BaseServlet {
/**
     * 创建 Cookie
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void createCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1、创建 Cookie 对象
        Cookie cookie = new Cookie("key1", "value1");
        Cookie cookie1 = new Cookie("key2", "value2");

        //2、通知客户端保存 cookie
        resp.addCookie(cookie);
        resp.addCookie(cookie1);

        resp.getWriter().write("Cookie创建成功!");
    }
}

BaseServlet抽象类代码

注意:此篇文章中所有的 Servlet 程序继承于该抽象类

/**
 * 
 * BaseServlet 抽象类,是用来通过根据 html(或jsp)中标签中 action 的属性值
 * 执行action值的同名方法
 *
 * @author Herz
 * @date 2021/4/5 9:53
 */
public abstract class BaseServlet 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 {
        req.setCharacterEncoding("UTF-8");

        //解决响应中文乱码
        resp.setContentType("text/html;charset=UTF-8");


        String action = req.getParameter("action");

//        if ("login".equalsIgnoreCase(action)){
//            login(req, resp);
//        }else if ("regist".equalsIgnoreCase(action)){
//            regist(req, resp);
//        }

        try {
            //获取action 业务鉴别字符串,获取相应的业务,通过获取方法反射对象
            Method method = this.getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);
            //调用目标业务方法
            method.invoke(this, req, resp);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

如何获取Cookie

Cookie与Session

实现代码如下:

public class CookieServlet extends BaseServlet {
/**
     * 获取 Cookie
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1、创建cookie数组 接收 获取的 cookie
        Cookie[] cookies = new Cookie[]{};
        //2、通过request.getCookies() 获取 cookie
        cookies = req.getCookies();
        for (Cookie cookie : cookies) {
            resp.getWriter().write("Cookie[" + cookie.getName() + "=" + cookie.getValue() + "]" + "<br/>");
        }

        Cookie iWantCookie = null;

        iWantCookie = CookieUtils.findCookie("key1", cookies);  

        if (iWantCookie != null) {
            resp.getWriter().write("找到了key 值为 key1 的 cookie,为:<br/>" + iWantCookie.getName() + "=" + iWantCookie.getValue());
        } else {
            resp.getWriter().write("没有找到 key值为key1 的 cookie !");
        }
    }
}

查找指定key值的Cookie(CookieUtils工具类)

/**
 * @author Herz
 * @date 2021/4/6 10:06
 */
public class CookieUtils {

    /**
     * 查找指定 key 的 cookie
     * @param name key 的指定 参数值
     * @param cookies  提供接收获取的 cookie 数组
     * @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.equalsIgnoreCase(cookie.getName())){
                return cookie;
            }
        }

        return null;
    }
}

Cookie值的修改

实现代码如下:

public class CookieServlet extends BaseServlet {
/**
     * 修改 Cookie 的 value值
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
        protected void updateCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //方案一:
        //1、创建同名的cookie
        //2、通过构造器改变 value 的值
//        Cookie cookie = new Cookie("key1", "newValue1");
        //3、通过 response.addCookie()  通知 客户端保存 cookie
//        resp.addCookie(cookie);


        //方案二:
        //1、先查找要修改的Cookie
        Cookie cookie = CookieUtils.findCookie("key2", req.getCookies());
        //2、调用 setValue() 修改 value 值
        cookie.setValue("newValue2");
        //3、通知 客户端保存 cookie
        resp.addCookie(cookie);

        resp.getWriter().write("key 值为 "+cookie.getName()+" 的cookie修改成功!为:Cookie[" + cookie.getName() + "=" + cookie.getValue() + "] <br/>");

    }
}

Cookie生命控制

Cookie的生命控制是指如何管理 Cookie 什么时候被销毁(删除)。
    使用 setMaxAge() 方法实现。
    其中参数如下:
            正数:表示在指定秒数后过期
            负数:表示浏览器一关,Cookie就会被删除(浏览器默认是负数)
            零:表示马上删除。

实现代码如下:

public class CookieServlet extends BaseServlet {
/**
         * 设置存活时间为 0 ,使 Cookie 立即删除
         * @param req
         * @param resp
         * @throws ServletException
         * @throws IOException
         */
    protected void deleteNow(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1、先找到要删除的Cookie 或者创建一个 Cookie
        Cookie cookie = CookieUtils.findCookie("key1", req.getCookies());

        if (cookie != null) {
            //2、调用 setMaxAge() 设置生存时间
            cookie.setMaxAge(0);  //表示立即删除,无需等待浏览器关闭
            //3、调用 response.addCookie() 通知客户端保存 Cookie
            resp.addCookie(cookie);

            resp.getWriter().write("key值为:"+cookie.getName()+"的Cookie删除成功!");
        }else {
            resp.getWriter().write("要修改生命周期的Cookie不存在!");
        }
    }

        /**
         * 设置 Cookie 默认生存时间
         * @param req
         * @param resp
         * @throws ServletException
         * @throws IOException
         */
    protected void defaultLife(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1、创建一个 cookie
        Cookie cookie = new Cookie("defaultLife", "defaultLife");
        //2、调用 setMaxAge() 设置存活时间
        cookie.setMaxAge(-1);  //表示浏览器关闭时删除Cookie
        //3、调用 response.addCookie() 通知客户端保存 Cookie
        resp.addCookie(cookie);
    }

/**
     * 设置存活时间为 3600秒
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
protected void life3600(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1、先找到要修改生存时间的Cookie 或者创建一个 Cookie
        Cookie cookie = CookieUtils.findCookie("Key2", req.getCookies());

        if (cookie != null) {
            //2、调用 setMaxAge() 修改生存时间
            cookie.setMaxAge(60 * 60);
            //3、调用 response.addCookie() 通知客户端保存Cookie
            resp.addCookie(cookie);

            resp.getWriter().write("key值为:"+cookie.getName()+"的Cookie声明周期成功修改为3600");
        }else {
            resp.getWriter().write("要修改生命周期的Cookie不存在!");
        }
    }
}

Cookie 有效路径Path设置

实现代码如下:

public class CookieServlet extends BaseServlet {
/**
     * 修改 Cookie 的 Path 路径
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void testPath(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie cookie = new Cookie("path1", "path1");
        // getContextPath() --->>>  http://ip:port/工程路径
        cookie.setPath(req.getContextPath() + "/abc");  // -->>>> http://ip:port/工程路径/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 {
        resp.setContentType("text/html;charset=UTF-8");

        String username = req.getParameter("username");
        String password = req.getParameter("password");


        if ("tianfei".equalsIgnoreCase(username)&&"tianfei".equalsIgnoreCase(password)){
            //登录成功
            Cookie cookie = new Cookie("username", username);
            cookie.setMaxAge(06 * 60 *24 * 7);  //Cookie 一周的生命周期
            resp.addCookie(cookie);
            resp.getWriter().write("登录成功!");
        }else {
            //登录失败
            resp.getWriter().write("登录失败!");
        }
    }
}
相应的登录界面 login.jsp

<%--
  Created by IntelliJ IDEA.
  User: Herz
  Date: 2021/4/6
  Time: 14:29
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="http://localhost:8080/Cookie_And_Session/loginServlet" method="get">
    用户名:<input type="text" name="username" value="${cookie.username.value}"><br/>
    密码:<input type="password" name="password"><br/>
    <input type="submit" value="登录">
</form>
</body>
</html>

!!!!注意:在写完 Servlet 程序后不要忘记在 web/WEB-INF/Web.xml 中配置相应servlet

什么是Session会话

    1、Session就是一个接口(HttpSession),保存在服务器。
    2、Session 会话,使用来维护一个客户端与服务器之间关联的一种技术。
    3、每一个客户端都有自己的一个Session会话。
    4、Session 会话中,通常用来保存用户登录之后的信息。

Session 的创建

Session会话的创建和获取的API都是用一个:requset.getSession();
当Session还未创建时,调用getSession() 创建一个Session会话。
在Session的有效期间,再调用getSession() 只能获取Session会话。通过 isNew() 判断是否是新创建的会话。

public class SessionServlet extends BaseServlet {
/**
     * 创建或获取 Seesion
     *
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void createOrGetSession(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //创建或获取Session
        HttpSession session = req.getSession();
        //判断 Seesion 是否是新创建的
        boolean isNew = session.isNew();
        //获取该Session的Id值
        String id = session.getId();


        resp.getWriter().write("新创建或者获取的 Session 的唯一Id为:" + id + "<br/>");

        resp.getWriter().write("获取的该Session是否为新创建的" + isNew + "<br/>");
    }
}

Session 域中数据的存储

public class SessionServlet extends BaseServlet {
/**
     * 保存 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 {
        Object attribute = req.getSession().getAttribute("key1");

        resp.getWriter().write("从Session取出key1的数据为:" + attribute);
    }
}

Session 生命周期的控制

    Seesion 超时指得是,客户端两次请求的最大间隔时间。
            setMaxInactiveInterval()的参数:
                    正数:设定Session会话超时时长
                    负数(极少使用):表示永不超时
    Session 会话默认超时时长为30分钟。
    如果要修改 web 工程所有的 Session 会话默认超时时长,可在 web/WEB-INF/web.xml 中设置:
                    <!--设置 web 工程中所有的 Session 会话默认的超时时长为20分钟-->
                    <session-config>
                                <session-timeout>20</session-timeout>
                    </session-config>
public class SessionServlet extends BaseServlet {
/**
     * 设置 Session 会话马上销毁
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    protected void downNow(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1、获取 Session 会话
        HttpSession session = req.getSession();
        //2、让 Session 会话马上超时
        session.invalidate();

        resp.getWriter().write("已将当前 Session 会话设置为立即销毁。");
    }


        /**
         * 设置 Session会的的超时时长
         * @param req
         * @param resp
         * @throws ServletException
         * @throws IOException
         */
    protected void life3(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.getSession().setMaxInactiveInterval(3);

        resp.getWriter().write("Session 的超时时长已成功设置为3秒。");
    }

        /**
         * 获取 Session 会话的默认超时时长
         * @param req
         * @param resp
         * @throws ServletException
         * @throws IOException
         */
    protected void defaultLife(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        int maxInactiveInterval = req.getSession().getMaxInactiveInterval();

        resp.getWriter().write("获取的Session 的默认超时时长为:" + maxInactiveInterval);
    }
}

浏览器与Session之间关联的技术内幕

Cookie与Session

!!!!注意:在写完 Servlet 程序后不要忘记在 web/WEB-INF/Web.xml 中配置相应servlet