13-Cookie

时间:2021-08-08
本文章向大家介绍13-Cookie,主要包括13-Cookie使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

1、Cookie

1、--Cookie是什么?作用?Cookie保存位置?
	-字面意思:
		翻译就是曲奇饼干,也是Cookie文件的意思
	-作用:
		Cookie可以保存的一个会话状态,使会话状态保存在客户端上
		Cookie被清除或者失效后,这个会话状态就没有了
	-保存位置:
		Cookie是保存在客户端浏览器上的,有两个位置:
		保存在浏览器的缓存中,是即时的,浏览器关闭后这种Cookie就会被清除
		保存在客户端的硬盘文件中,有保存期限,在该期限内关闭浏览器Cookie不会被清除,除非手动删除或过期失效
		
2、--哪些开发中有Cookie?
	只要是web开发,是B/S架构系统,基于HTTP协议的开发都有Cookie的存在
	所以说Cookie不只是存在于javaweb中
	Cookie这种机制是HTTP协议规定的。也就是W3C制定的

3、--我们所熟悉Cookie实现的功能?
	-在京东购物网上未登录添加商品进购物车的状态保留在客户端上
	-实现十天免登录
	...
	
4、--在Java中,Cookie是一种类class,存在于Servlet规范中,所以new出Cookie对象
	需要注意的是javax.servlet.http.Cookie这个类中,是没有无参的构造方法的。
	其构造方法需要传两个String类型的参数,两参数含义是name和value。所以说new出的Cookie对象由name和value两部
	分组成
	
5、--怎么创建Cookie?
	Cookie cookie = new Cookie(String name,String value);
	
6、--服务器可以一次性向客户端发送多个Cookie

7、--默认情况下,服务器发送到浏览器的Cookie被保存在浏览器的缓存中,浏览器不关闭,Cookie一直存在且有效,浏览器	 被关闭后Cookie立马被清除

8、--那么存在于浏览器缓存或者是其硬盘文件中的Cookie,什么时候会被浏览器发送给服务器?
	-浏览器要提交这些保存的Cookie,跟请求路径有关系
	-请求路径与Cookie紧密关联
	-不同的请求路径可以发送不同的Cookie
	
9、--默认情况下,被保存的Cookie和哪些路径绑定?
	我们用这样的请求路径:
	-- /idea_servlet_http_cookie_11_war_exploded/test/createAndSendCookieToBrowser
	将Cookie从服务器"发送"给客户端
	这个被浏览器保存的Cookie"默认"和test/路径绑定在一起:
	就是说这个Cookie存在还在有效时间,发起test/路径的请求:
    --http://IP:port/idea_servlet_http_cookie_11_war_exploded/test/
    或者这样
    --http://IP:port/idea_servlet_http_cookie_11_war_exploded/test/a
    Cookie一定会被提交给服务器
    下面没有test/路径的就不会提交Cookie:
    --http://IP:port/idea_servlet_http_cookie_11_war_exploded/test1/a
    和这样的
	--http://IP:port/idea_servlet_http_cookie_11_war_exploded/test
	经过测试:
	--/idea_servlet_http_cookie_11_war_exploded/a
	将Cookie从服务器发送给客户端
	这个被浏览器保存的Cookie默认和idea_servlet_http_cookie_11_war_exploded/路径绑定在一起
	
	"就是说默认绑定的路径是和截掉资源部分的路径(/保存)进行绑定的,只要是请求路径前面包含被绑定的路径,无论后面
	添加的是什么请求路径都会发送cookie给服务器"
	
10、--发送的Cookie是可以在创建该Cookie后进行请求路径绑定的
	假设在java程序中执行了这样的程序:cookie.setPath("idea_servlet_http_cookie_11_war_exploded/king");
	这个Cookie就会和"idea_servlet_http_cookie_11_war_exploded/king"路径绑定在一起
	
11、--默认情况下,如果在创建Cookie后没有设置其有效时长,该Cookie被发送到客户端浏览器后是被存储在浏览器的缓存当中的,这样的Cookie是和浏览器共存亡的,浏览器被关闭就会被清除。当我们设置了Cookie的有效时间后,Cookie就会保存到浏览器的的硬盘文件中,在有效时间内,如果不手动删除这个Cookie,这个Cookie不会受浏览器的关闭影响。有效期过后,该Cookie就失效了。
设置方法如下:
--Cookie中有这样一个方法:
 public void setMaxAge(int expiry) {
        this.maxAge = expiry;
    }
	需要注意的是:
	设置的单位是秒seconds
		Cookie有效时间 expiry = 0 表示Cookie直接被删除
		Cookie有效时间 expiry < 0 表示Cookie不被存储
		Cookie有效时间 expiry > 0 表示Cookie被存储到硬盘文件中
	--存储在浏览器客户端的硬盘文件路径是打开浏览器的工具->Internet选项->常规->设置-查看文件
	
12、--当浏览器发送Cookie给服务器,服务器怎么接收呢?
	需要用到HttpServletRequest接口中的getCookies()方法
	Cookie[] cookies = request.getCookies();
	
	Cookie[] cookies = request.getCookies();
        if (cookies != null){
            for (Cookie cookie:
                 cookies) {
                System.out.println(cookie.getName()+" = "+cookie.getValue());
            }
        }
       
13、--浏览器是可以禁用Cookie的
	在Internet选项中选择隐私进行设置,这是IE浏览器的设置。
	意思是服务器发送过来的Cookie被浏览器拒收了
	这只是浏览器不接收Cookie,服务器该发送的还是会发送。

2、创建web项目测试Cookie

2.1 web.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--设置欢迎页面,-->
    <welcome-file-list>
        <welcome-file>html/cookie.html</welcome-file>
    </welcome-file-list>
    
    <servlet>
        <servlet-name>cookie</servlet-name>
        <servlet-class>com.servlet.http.CreateAndSendCookieToBrowser</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>cookie</servlet-name>
        <url-pattern>/test/createAndSendCookieToBrowser</url-pattern>
    </servlet-mapping>
</web-app>

2.2 cookie.html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>cookie page</title>
</head>
<body>
    <a href="/idea_servlet_http_cookie_11_war_exploded/test/creatAndSendCookieToBrowser">服务器创建Cookie并发送到浏览器1</a>
</body>
</html>

2.3 CreateAndSendCookieToBrowser.java

package com.servlet.http;

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 CreateAndSendCookieToBrowser extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //创建Cookie对象
        Cookie cookie1 = new Cookie("username","zhangsan");
        Cookie cookie2 = new Cookie("password","123");
        
        //绑定Cookie的请求路径
        cookie1.setPath(request.getContextPath()+"/king");
        cookie2.setPath(request.getContextPath()+"/king");

        //将Cookie发送给浏览器客户端,到浏览器肯定是响应,所以用response
        response.addCookie(cookie1);
        response.addCookie(cookie2);

    }
}

部署项目启动服务器,跳转到欢迎页面如下:

2.4 打开HttpWatch,开始监测,点击链接,监测结果如下

可以看到响应协议中,有两个Cookie对象被响应而发送了过来,此时这两个Cookie被默认保存到了浏览器的缓存中

3、测试Cookie和请求路径的绑定

下面截图中是学习课程中的,所以部署的项目名不一样。
可以看到请求协议中提交了保存的两个Cookie

========================================

看到请求协议中还是提交了保存的两个Cookie

===========================================================================

可以看到将test/变为test1/后,并没有提交Cookie

就是说默认情况下保存的Cookie与发送自己的请求路径中的test/路径绑定在一起的

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--设置欢迎页面,-->
    <welcome-file-list>
        <welcome-file>html/cookie.html</welcome-file>
    </welcome-file-list>
    
    <servlet>
        <servlet-name>cookie</servlet-name>
        <servlet-class>com.servlet.http.CreateAndSendCookieToBrowser</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>cookie</servlet-name>
        <url-pattern>/test/createAndSendCookieToBrowser</url-pattern>
        <url-pattern>/a</url-pattern>
    </servlet-mapping>
</web-app>

我们打开HttpWatch打开监测

将请求路径:http://localhost:8080/idea_servlet_http_cookie_11_war_exploded/a进行刷新

看到监测结果在中请求协议部分并没有发送Cookie

将请求路径改为:http://localhost:8080/idea_servlet_http_cookie_11_war_exploded/

请求协议中发送了Cookie。

将请求路径改为:http://localhost:8080/idea_servlet_http_cookie_11_war_exploded

请求协议中没有发送Cookie。

所以说http://localhost:8080/idea_servlet_http_cookie_11_war_exploded/a路径发送的Cookie绑定的路径是:

idea_servlet_http_cookie_11_war_exploded/

默认的绑定路径规律像是发送这个Cookie的请求路径去掉最后面的路径名,这只是猜测。

在绑定路径后我们通过监测请求路径,从响应协议中可以看到Cookie所绑定的关联路径,如下图:

设置有效时长后监测到的响应协议中看到Cookie的有效截至时间,如下图

4、测试浏览器提交Cookie到服务器,服务器接收

cookie.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>cookie page</title>
</head>
<body>
    <a href="/idea_servlet_http_cookie_11_war_exploded/test/createAndSendCookieToBrowser">服务器创建Cookie并发送到浏览器1</a>
    <br>
    <a href="/idea_servlet_http_cookie_11_war_exploded/a">服务器创建Cookie并发送到浏览器2</a>
    <br>
    <a href="/idea_servlet_http_cookie_11_war_exploded/test/browserSendCookieToServer">浏览器发送Cookie到服务器</a>
</body>
</html>
web.xml
	<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--设置欢迎页面,-->
    <welcome-file-list>
        <welcome-file>html/cookie.html</welcome-file>
    </welcome-file-list>
    
    <servlet>
        <servlet-name>cookie</servlet-name>
        <servlet-class>com.servlet.http.CreateAndSendCookieToBrowser</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>cookie</servlet-name>
        <url-pattern>/test/createAndSendCookieToBrowser</url-pattern>
        <url-pattern>/a</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>bscts</servlet-name>
        <servlet-class>com.servlet.http.RecieveCookiesServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>bscts</servlet-name>
        <!--注意该路径中要添加test/与上面发送Cookie的路径绑定部分-->
        <url-pattern>/test/browserSendCookieToServer</url-pattern>
    </servlet-mapping>
</web-app>
RecieveCookiesServlet.java
package com.servlet.http;

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 RecieveCookiesServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //从request对象中获取所有提交的Cookie,放进一个数组中
        Cookie[] cookies = request.getCookies();

        if (cookies != null){
            for (Cookie cookie:
                 cookies) {
                System.out.println(cookie.getName()+" = "+cookie.getValue());
            }
        }

    }
}

CreateAndSendCookieToBrowser.java
package com.servlet.http;

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 CreateAndSendCookieToBrowser extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //创建Cookie对象
        Cookie cookie1 = new Cookie("username","zhangsan");
        Cookie cookie2 = new Cookie("password","123");

        //绑定Cookie的请求路径
//        cookie1.setPath(request.getContextPath()+"/king");
//        cookie2.setPath(request.getContextPath()+"/king");

        //设置Cookie有效时长
        cookie1.setMaxAge(60*60);//有效时长一个小时
        cookie2.setMaxAge(60*60*24);//有效时长一天

        //将Cookie发送给浏览器客户端,到浏览器肯定是响应,所以用response
        response.addCookie(cookie1);
        response.addCookie(cookie2);

    }
}

确保浏览器保存了Cookie,然后点击下图第三个链接,服务器窗口输出如下

5、实现十天免登陆

5.1 首先要完成的是创建程序实现登录功能

5.3 登录功能实现的代码如下

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    
    <welcome-file-list>
        <welcome-file>html/login.html</welcome-file>
    </welcome-file-list>
    
    <servlet>
        <servlet-name>login</servlet-name>
        <servlet-class>com.servlet.http.cookie.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>login</servlet-name>
        <url-pattern>/cookie/login</url-pattern>
    </servlet-mapping>
</web-app>
login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录页面</title>
</head>
<body>
    <form action="/idea-servlet-cookie/cookie/login" method="post">
        用户名<input type="text" name="loginName"><br>
        密  码<input type="password" name="loginPwd"><br>
        <input type="submit" value="LOGIN">
    </form>
</body>
</html>
login-error.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>输入错误</title>
</head>
<body>
    <form action="/idea-servlet-cookie/html/login.html" method="get">
        用户名或密码错误,请重新<input type="submit" value="登录">
    </form>
</body>
</html>
LoginServlet.java
package com.servlet.http.cookie;

import com.servlet.http.utils.DBUtil;

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;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class LoginServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        request.setCharacterEncoding("UTF-8");
        //获取请求提交表单数据request
        String loginName = request.getParameter("loginName");
        String loginPwd = request.getParameter("loginPwd");
//      System.out.println(loginName+"\n"+loginPwd);

        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        boolean loginSuccess = false;
        String realName = null;

        try {
            //注册驱动和获取连接
            conn = DBUtil.getConnection();

            //获取数据库操作对象
            String sql = "select loginName,loginPwd,realName from t_user where loginName=? and loginPwd=?";
            //需要注意的是先编译sql语句在传?的值,不然报空指针异常
            ps = conn.prepareStatement(sql);
            ps.setString(1,loginName);
            ps.setString(2,loginPwd);


            //执行sql语句
            rs = ps.executeQuery();

            //处理查询结果集
            if (rs.next()){
                loginSuccess = true;
                realName = rs.getString(3);
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        if (loginSuccess){
            
              //判断是否选择了十天免登录
            if ("ok".equals(request.getParameter("TenDayAutoLoginFlag"))){
                //创建Cookie对象
                Cookie cookie1 = new Cookie("loginName",loginName);
                Cookie cookie2 = new Cookie("loginPwd",loginPwd);
                //绑定Cookie路径
                cookie1.setPath(request.getContextPath());
                cookie2.setPath(request.getContextPath());
                //设定有效时长
                cookie1.setMaxAge(60*60*24*10);
                cookie2.setMaxAge(60*60*24*10);
                //发送Cookie
                response.addCookie(cookie1);
                response.addCookie(cookie2);
            }

            //设置输出到浏览器的字符类型和编码方式
            response.setContentType("text/html;charset=UTF-8");

            PrintWriter out = response.getWriter();

            out.print("<html >");
            out.print("<head>");
            out.print("</head>");
            out.print("<body>");
            out.print("欢迎用户:"+realName+"<br>登录本操作系统");
            out.print("</body>");
            out.print("</html>");

        }else {
            response.sendRedirect("/idea-servlet-cookie/html/login-error.html");
        }
    }
}

要实现十天免登录,首先在登录页面添加一个“十天免登录”选项

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录页面</title>
</head>
<body>
    <form action="/idea-servlet-cookie/cookie/login" method="post">
        用户名<input type="text" name="loginName"><br>
        密  码<input type="password" name="loginPwd"><br>
        <!--十天免登录选项-->
        <input type="checkbox" name="TenDayAutoLoginFlag" value="ok">十天内免登录<br>
        <input type="submit" value="LOGIN">
    </form>
</body>
</html>

其次需要修改欢迎页面,不能把登录页面作为欢迎页面,我们创建一个Servlet类CheckLoginStatusServlet.java,将这个判断类作为欢迎页面。这个类获取Cookie,通过获取Cookie中的value值是否为空,判断是否要转到登录页面,还是用Cookie保存的登录名和密码跳转到上次登陆后的页面。

修改的web.xml如下
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    
     <!--将核查cookie的Servlet对象作为欢迎页面-->
    <welcome-file-list>
        <welcome-file>cookie/checkLogin</welcome-file>
    </welcome-file-list>
    
    <servlet>
        <servlet-name>login</servlet-name>
        <servlet-class>com.servlet.http.cookie.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>login</servlet-name>
        <url-pattern>/cookie/login</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>checkLogin</servlet-name>
        <servlet-class>com.servlet.http.cookie.CheckLoginStatusServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>checkLogin</servlet-name>
        <url-pattern>/cookie/checkLogin</url-pattern>
    </servlet-mapping>
</web-app>
判断Servlet类如下:CheckLoginStatusServlet.java
package com.servlet.http.cookie;

import com.servlet.http.utils.DBUtil;

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;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class CheckLoginStatusServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //获取request中的Cookie
        Cookie[] cookies = request.getCookies();

        String loginName = null;
        String loginPwd = null;

        if (cookies != null) {

            for (Cookie cookie:
                 cookies) {
                String cookieName = cookie.getName();
                String cookieValue = cookie.getValue();
                if ("loginName".equals(cookieName)){
                    loginName =  cookieValue;
                }else if ("loginPwd".equals(cookieName)){
                    loginPwd = cookieValue;
                }
            }

        }

        if (loginName != null && loginPwd != null) {


            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            boolean loginSuccess = false;
            String realName = null;

            try {
                //注册驱动和获取连接
                conn = DBUtil.getConnection();

                //获取数据库操作对象
                String sql = "select loginName,loginPwd,realName from t_user where loginName=? and loginPwd=?";
                //需要注意的是先编译sql语句在传?的值,不然报空指针异常
                ps = conn.prepareStatement(sql);
                ps.setString(1,loginName);
                ps.setString(2,loginPwd);


                //执行sql语句
                rs = ps.executeQuery();

                //处理查询结果集
                if (rs.next()){
                    loginSuccess = true;
                    realName = rs.getString(3);
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
            if (loginSuccess){

                //设置输出到浏览器的字符类型和编码方式
                response.setContentType("text/html;charset=UTF-8");

                PrintWriter out = response.getWriter();

                out.print("<html >");
                out.print("<head>");
                out.print("</head>");
                out.print("<body>");
                out.print("欢迎用户:"+realName+"<br>登录本操作系统");
                out.print("</body>");
                out.print("</html>");

            }
        } else {
            response.sendRedirect(request.getContextPath()+"/html/login.html");
        }
        }


}

然后通过在两个Servle类中添加断点进行Debug,首先是一步一步的往下走,如果走不动了点击debug页面左端的绿色播放按钮,就可以调到另一个Servlet类中的断点,继续一步一步走了

原文地址:https://www.cnblogs.com/rjzhong/p/15114559.html