Servlet17—— Cookie

Cookie概述

Cookie是由服务器端生成并储存在浏览器客户端上的数据,只要Cookie清除或者Cookie失效,这个会话状态就没有了。当然,Cookie也可以保存在浏览器的缓存中,浏览器关闭Cookie消失。

javaweb开发中Cookie被当做java对象在web服务器端创建,并由web务器发送给特定浏览器客户端,并且WEB服务器可以向同一个浏览器客户端上同时发送多个Cookie,每一个Cookie对象都由namevalue组成,namevalue只能是字符串类型,浏览器接收到来自服务器的Cookie数据之后默认将其保存在浏览器缓存中(如果浏览器关闭,缓存消失,Cookie数据消失),只要浏览器不关闭,当我们下一次发送“特定”请求的时候,浏览器负责将Cookie数据发送给WEB服务器。我们还可以使用特殊的方法,将Cookie保存在客户端的硬盘上。永久性保存。这样关闭浏览器Cookie还是存在的,不会消失,比如:实现两周内自动登录。

Cookie不止在javaweb中存在,只要是web开发,只要是B/S架构的系统,只要是基于HTTP协议,就有Cookie的存在,Cookie这种机制是HTTP协议规定的。

Cookie在现实生活中对应的场景

Cookie在客户端的保存形式和有效时间

服务器端默认创建的Cookie,发送到浏览器之后,浏览器默认将其保存在缓存中,当浏览器关闭之后Cookie消失,。在java程序中创建Cookie

Cookie cookie = new Cookie(String cookieName, String cookieValue);

在浏览器客户端无论是硬盘文件中还是缓存中保存的Cookie,什么时候会再次发送给服务器呢?

  • 浏览器会不会提交发送这些Cookie给服务器,和请求路径有关系。
  • 请求路径和Cookie是紧密关联的。
  • 不同的请求路径会发送提交不同的Cookie

默认情况下Cookie会和哪些路径绑定在一起?

若是项目中部署的路径

  • /prj-servlet-18/test/createAndSendCookieToBrowser 请求服务器,服务器生成Cookie,并将Cookie发送给浏览器客户端,这个浏览器中的Cookie会默认和“test/”这个路径绑定在一起。也就是说,以后只要发送“test/”请求,Cookie一定会提交给服务器。

若存在servlet中的路径

  • /prj-servlet-18/a 请求服务器,服务器生成Cookie,并将Cookie发送给浏览器客户端,这个浏览器中的Cookie会默认和“prj-servlet-18/”这个路径绑定在一起。也就是说,以后只要发送“prj-servlet-18/”请求,Cookie一定会提交给服务器。

其实路径是可以指定的,可以通过java程序进行设置,保证Cookie和某个特定的路径绑定在一起。假设,执行了这样的程序:cookie.setPath("/prj-servlet-18/king");    那么:Cookie将和"/prj-servlet-18/king"路径绑定在一起,只有发送“/prj-servlet-18/king”请求路径,浏览器才会提交Cookie给服务器。

服务器创建Cookie对象之后,调用setMaxAge方法设置Cookie的有效时间。默认情况下,没有设置Cookie的有效时长,该Cookie被默认保存在浏览器的缓存当中,只要浏览器不关闭Cookie存在,只要关闭浏览器Cookie消失,我们可以通过设置Cookie的有效时长,以保证Cookie保存在硬盘文件当中。但是这个有效时长必须是>0的。换句话说,只要设置Cookie的有效时长大于0,则该Cookie会被保存在客户端硬盘文件当中。有效时长过去之后,则硬盘文件当中的Cookie失效。

  • 如果这个有效时间 >0,则该Cookie对象发送给浏览器之后浏览器将其保存到硬盘文件中。
  • 如果这个有效时间 <0,则该Cookie对象也是被保存在浏览器缓存中,待浏览器关闭Cookie消失。
  • 如果这个有效时间 =0,则该Cookie从服务器端发过来的时候就已经是一个已过时的Cookie

cookie.setMaxAge(60 * 60); //1小时有效,参数以second为单位

浏览器提交Cookie给服务器,服务器怎么接收Cookie?

Cookie[] cookies = request.getCookies();

if(cookies != null){

  for(Cookie cookie : cookies){

    String cookieName = cookie.getName();

    String cookieValue = cookie.getValue();

    System.out.println(cookieName + "=" + cookieValue);

  }

}

Cookie和请求路径之间的关系

每一个Cookie和请求路径是绑定在一起的,只有特定的路径才可以发送特定的Cookie。实际上浏览器是这样做的:浏览器在向web服务器发送请求的时候先去对应的请求路径下搜索是否有对应的Cookie,如果有Cookie,并且Cookie没有失效,则发送该Cookie或者多个Cookie到服务器端。请求路径和Cookie的关系是这样对应的:

假如获取Cookie时的路径是 :http://127.0.0.1:8080/PrjCookies/getCookie

将来发送Cookie的路径包括如下路径 :

假如获取Cookie时的路径是 :http://127.0.0.1:8080/PrjCookies/servlet/getCookie

将来发送Cookie的路径包括如下路径 :

不过我们也可以在创建Cookie对象的时候设置Cookie的关联路径,例如:cookie.setPath(“/PrjCookies/system/login”);那么如下的请求路径浏览器会发送该Cookie

浏览器禁用Cookie

浏览器是可以禁用Cookie,表示服务器发送过来的Cookie,我浏览器不要,不接收。服务器还是会发送Cookie的,只不过浏览器不再接收。

IE浏览器禁用Cookie

当浏览器禁用Cookie之后,服务器还是仍然会将Cookie发送给浏览器,只不过这次浏览器选择了不接收。现在有很多网站的使用都是需要开启接收Cookie的。例如126邮箱。

 

Cookie实现“两周内自动登录”

 附:

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    
    <welcome-file-list>
        <welcome-file>isLogin</welcome-file>
    </welcome-file-list>
    
    <servlet>
        <servlet-name>login</servlet-name>
        <servlet-class>myweb.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>login</servlet-name>
        <url-pattern>/login</url-pattern>
    </servlet-mapping>
    
    <servlet>
        <servlet-name>isLogin</servlet-name>
        <servlet-class>myweb.CheckLoginStatusServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>isLogin</servlet-name>
        <url-pattern>/isLogin</url-pattern>
    </servlet-mapping>
</web-app>

login.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
  <head>
    <title>登录页面</title>
    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

  </head>
  
  <body>
      
      <form action="/Servlet-11/login" method="post">
          用户名
              <input type="text" name="username" >
              <br>
          密码
              <input type="password" name="password">
              <br>
          <input type="checkbox" name="tenDayAutoLoginFlag" value="ok">十天内免登录<br>
          <input type="submit" value="登录">
      </form>
      
  </body>
</html>

login-error.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
  <head>
    <title>登录失败</title>
    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->

  </head>
  
  <body>
  
      登录失败,用户名不存在或者密码错误,请<a href="/Servlet-11/login.html">重新登录</a>
      
  </body>
</html>

CheckLoginStatusServlet.java

package myweb;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CheckLoginStatusServlet extends HttpServlet {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        //从request中获取所有的Cookie
        Cookie[] cookies = request.getCookies();
        String username = null;
        String password = null;
        if(cookies != null){
            //遍历Cookie
            for(Cookie cookie : cookies){
                String cookieName = cookie.getName();
                String cookieValue = cookie.getValue();
                if("username".equals(cookieName)){
                    username = cookieValue;
                }else if("password".equals(cookieName)){
                    password = cookieValue;
                }
            }
        }
        
        if(username != null && password != null){
            //连接数据库JDBC验证用户名和密码
            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            boolean loginSuccess = false;
            String realName = null;
            try {
                Class.forName("com.mysql.jdbc.Driver");
                conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/MySQL", "root", "root");
                String sql = "select id,username,password,realname from login.t_user where username=? and password=?";
                ps = conn.prepareStatement(sql);
                ps.setString(1, username);
                ps.setString(2, password);
                rs = ps.executeQuery();
                if(rs.next()){
                    loginSuccess = true;
                    realName = rs.getString("realname");
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally{
                if(rs != null){
                    try {
                        rs.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
                if(ps != null){
                    try {
                        ps.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
                if(conn != null){
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
            
            if(loginSuccess){
                //登录成功跳转到成功页面
                response.setContentType("text/html;charset=UTF-8");
                PrintWriter out = response.getWriter();
                out.print("<html>");
                out.print("<head>");
                out.print("<title>欢迎页面</title>");
                out.print("</head>");
                out.print("<body>");
                out.print("欢迎");
                out.print(realName);
                out.print("访问");
                out.print("</body>");
                out.print("</html>");
            }else{
                //登录失败跳转到失败页面
                response.sendRedirect(request.getContextPath() + "/login-error.html");
            }
        }else{
            //跳转到登录页面
            response.sendRedirect(request.getContextPath() + "/login.html");
        }
        
    }

}

LoginServlet.java

package myweb;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoginServlet extends HttpServlet {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //获取用户名和密码
        request.setCharacterEncoding("UTF-8");
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        //JDBC连接数据库验证用户名和密码
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        boolean loginSuccess = false;
        String realName = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/MySQL", "root", "root");
            String sql = "select id,username,password,realname from login.t_user where username=? and password=?";
            ps = conn.prepareStatement(sql);
            ps.setString(1, username);
            ps.setString(2, password);
            rs = ps.executeQuery();
            if(rs.next()){
                loginSuccess = true;
                realName = rs.getString("realname");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally{
            if(rs != null){
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(ps != null){
                try {
                    ps.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(conn != null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        
        if(loginSuccess){
            //登录成功之后,获取用户是否选择了十天内免登录
            String tenDayAutoLoginFlag = request.getParameter("tenDayAutoLoginFlag");
            if("ok".equals(tenDayAutoLoginFlag)){
                //创建Cookie对象
                Cookie cookie1 = new Cookie("username",username);
                Cookie cookie2 = new Cookie("password",password);
                //设置有效时间
                cookie1.setMaxAge(60 * 60 * 24 * 10);
                cookie2.setMaxAge(60 * 60 * 24 * 10);
                //设置关联路径
                cookie1.setPath(request.getContextPath());
                cookie2.setPath(request.getContextPath());
                //发送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("<title>欢迎页面</title>");
            out.print("</head>");
            out.print("<body>");
            out.print("欢迎");
            out.print(realName);
            out.print("访问");
            out.print("</body>");
            out.print("</html>");
        }else{
            //登录失败跳转到失败页面
            response.sendRedirect(request.getContextPath() + "/login-error.html");
        }
        
    }

}

use login;
drop table if exists t_user;
create table t_user(
    id int(10) primary key auto_increment,
    username varchar(32) not null unique,
    password varchar(32) not null,
    realname varchar(128)
);

insert into t_user(username,password,realname) values('admin','123','管理员');
insert into t_user(username,password,realname) values('zhangsan','123','张三');
commit;
select * from t_user;

 

 

转载请注明出处:https://www.cnblogs.com/stu-jyj3621
原文地址:https://www.cnblogs.com/stu-jyj3621/p/14370990.html