JavaWeb学习——Servlet的Cookie与Session[4]

Cookie 处理

Cookie 是存储在客户端计算机上的文本文件,并保留了各种跟踪信息。Java Servlet 显然支持 HTTP Cookie。

识别返回用户包括三个步骤:

  • 服务器脚本向浏览器发送一组 Cookie。例如:姓名、年龄或识别号码等。
  • 浏览器将这些信息存储在本地计算机上,以备将来使用。
  • 当下一次浏览器向 Web 服务器发送任何请求时,浏览器会把这些 Cookie 信息发送到服务器,服务器将使用这些信息来识别用户。
  • String   str   =   java.net.URLEncoder.encode("中文""UTF-8");            //编码
    String   str   =   java.net.URLDecoder.decode("编码后的字符串","UTF-8");   // 解码
    

    Cookie剖析

    Cookie 通常设置在 HTTP 头信息中(虽然 JavaScript 也可以直接在浏览器上设置一个 Cookie)。设置 Cookie 的 Servlet 会发送如下的头信息:

    HTTP/1.1 200 OK
    Date: Fri, 04 Feb 2000 21:03:38 GMT
    Server: Apache/1.3.9 (UNIX) PHP/4.0b3
    Set-Cookie: name=xyz; expires=Friday, 04-Feb-07 22:03:38 GMT; 
                     path=/; domain=runoob.com
    Connection: close
    Content-Type: text/html
    

    正如您所看到的,Set-Cookie 头包含了一个名称值对、一个 GMT 日期、一个路径和一个域。名称和值会被 URL 编码。expires 字段是一个指令,告诉浏览器在给定的时间和日期之后"忘记"该 Cookie。

    如果浏览器被配置为存储 Cookie,它将会保留此信息直到到期日期。如果用户的浏览器指向任何匹配该 Cookie 的路径和域的页面,它会重新发送 Cookie 到服务器。

    Servlet 就能够通过请求方法 request.getCookies() 访问 Cookie,该方法将返回一个 Cookie 对象的数组。

    方法描述
    public void setDomain(String pattern)该方法设置 cookie 适用的域,例如 runoob.com。
    public String getDomain()该方法获取 cookie 适用的域,例如 runoob.com。
    public void setMaxAge(int expiry)该方法设置 cookie 过期的时间(以秒为单位)。如果不这样设置,cookie 只会在当前 session 会话中持续有效。
    public int getMaxAge()该方法返回 cookie 的最大生存周期(以秒为单位),默认情况下,-1 表示 cookie 将持续下去,直到浏览器关闭。
    public String getName()该方法返回 cookie 的名称。名称在创建后不能改变。
    public void setValue(String newValue)该方法设置与 cookie 关联的值。
    public String getValue()该方法获取与 cookie 关联的值。
    public void setPath(String uri)该方法设置 cookie 适用的路径。如果您不指定路径,与当前页面相同目录下的(包括子目录下的)所有 URL 都会返回 cookie。
    public String getPath()该方法获取 cookie 适用的路径。
    public void setSecure(boolean flag)该方法设置布尔值,表示 cookie 是否应该只在加密的(即 SSL)连接上发送。
    public void setComment(String purpose)设置cookie的注释。该注释在浏览器向用户呈现 cookie 时非常有用。
    public String getComment()获取 cookie 的注释,如果 cookie 没有注释则返回 null。

    通过 Servlet 设置 Cookie

    通过 Servlet 设置 Cookie 包括三个步骤:

    (1) 创建一个 Cookie 对象:您可以调用带有 cookie 名称和 cookie 值的 Cookie 构造函数,cookie 名称和 cookie 值都是字符串。
    Cookie cookie = new Cookie("key","value");
    请记住,无论是名字还是值,都不应该包含空格或以下任何字符:
    [ ] ( ) = , " / ? @ : ;
    (2) 设置最大生存周期:您可以使用 setMaxAge 方法来指定 cookie 能够保持有效的时间(以秒为单位)。下面将设置一个最长有效期为 24 小时的 cookie。
    cookie.setMaxAge(60*60*24);
    (3) 发送 Cookie 到 HTTP 响应头:您可以使用 response.addCookie 来添加 HTTP 响应头中的 Cookie,如下所示:
    response.addCookie(cookie);

    cookie实例

    package com.runoob.test;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.net.URLEncoder;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * Servlet implementation class HelloServlet
     */
    @WebServlet("/HelloForm")
    public class HelloForm extends HttpServlet {
        private static final long serialVersionUID = 1L;
           
        /**
         * @see HttpServlet#HttpServlet()
         */
        public HelloForm() {
            super();
            // TODO Auto-generated constructor stub
        }
    
        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
         */
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
        {
            // 为名字和姓氏创建 Cookie      
            Cookie name = new Cookie("name",
                    URLEncoder.encode(request.getParameter("name"), "UTF-8")); // 中文转码
            Cookie url = new Cookie("url",
                          request.getParameter("url"));
            
            // 为两个 Cookie 设置过期日期为 24 小时后
            name.setMaxAge(60*60*24); 
            url.setMaxAge(60*60*24); 
            
            // 在响应头中添加两个 Cookie
            response.addCookie( name );
            response.addCookie( url );
            
            // 设置响应内容类型
            response.setContentType("text/html;charset=UTF-8");
            
            PrintWriter out = response.getWriter();
            String title = "设置 Cookie 实例";
            String docType = "<!DOCTYPE html>\n";
            out.println(docType +
                    "<html>\n" +
                    "<head><title>" + title + "</title></head>\n" +
                    "<body bgcolor=\"#f0f0f0\">\n" +
                    "<h1 align=\"center\">" + title + "</h1>\n" +
                    "<ul>\n" +
                    "  <li><b>站点名:</b>:"
                    + request.getParameter("name") + "\n</li>" +
                    "  <li><b>站点 URL:</b>:"
                    + request.getParameter("url") + "\n</li>" +
                    "</ul>\n" +
                    "</body></html>");
            }//这里是servlet,在获取了cookie后直接输出生成页面
    
        /**
         * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            doGet(request, response);
        }
    
    }
    

    其中,核心代码是这块:

    // 为名字和姓氏创建 Cookie      
            Cookie name = new Cookie("name",
                    URLEncoder.encode(request.getParameter("name"), "UTF-8")); // 中文转码
            Cookie url = new Cookie("url",
                          request.getParameter("url"));
            
            // 为两个 Cookie 设置过期日期为 24 小时后
            name.setMaxAge(60*60*24); 
            url.setMaxAge(60*60*24); 
            
            // 在响应头中添加两个 Cookie
            response.addCookie( name );
            response.addCookie( url );
    

    然后在写一个html用作输入和转发

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>菜鸟教程(runoob.com)</title>
    </head>
    <body>
    <form action="/TomcatTest/HelloForm" method="GET">
    站点名 :<input type="text" name="name">
    <br />
    站点 URL:<input type="text" name="url" /><br>
    <input type="submit" value="提交" />
    </form>
    </body>
    </html>
    

    保存上面的 HTML 内容到文件 /TomcatTest/test.html 中。

    接下来我们访问http://localhost:8080/TomcatTest/test.html
    就能发现我们写的cookie在2个不同的页面间生效了

    通过 Servlet 读取 Cookie

    要读取 Cookie,您需要通过调用 HttpServletRequestgetCookies( ) 方法创建一个 javax.servlet.http.Cookie 对象的数组。然后循环遍历数组,并使用 getName()getValue() 方法来访问每个 cookie 和关联的值。

    package com.runoob.test;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.net.URLDecoder;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * Servlet implementation class ReadCookies
     */
    @WebServlet("/ReadCookies")
    public class ReadCookies extends HttpServlet {
        private static final long serialVersionUID = 1L;
           
        /**
         * @see HttpServlet#HttpServlet()
         */
        public ReadCookies() {
            super();
            // TODO Auto-generated constructor stub
        }
    
        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
         */
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
        {
            Cookie cookie = null;
            Cookie[] cookies = null;
            // 获取与该域相关的 Cookie 的数组
            cookies = request.getCookies();
             
             // 设置响应内容类型
             response.setContentType("text/html;charset=UTF-8");
        
             PrintWriter out = response.getWriter();
             String title = "Delete Cookie Example";
             String docType = "<!DOCTYPE html>\n";
             out.println(docType +
                       "<html>\n" +
                       "<head><title>" + title + "</title></head>\n" +
                       "<body bgcolor=\"#f0f0f0\">\n" );
              if( cookies != null ){
                out.println("<h2>Cookie 名称和值</h2>");
                for (int i = 0; i < cookies.length; i++){
                   cookie = cookies[i];
                   if((cookie.getName( )).compareTo("name") == 0 ){
                        cookie.setMaxAge(0);
                        response.addCookie(cookie);
                        out.print("已删除的 cookie:" + 
                                     cookie.getName( ) + "<br/>");
                   }
                   out.print("名称:" + cookie.getName( ) + ",");
                   out.print("值:" +  URLDecoder.decode(cookie.getValue(), "utf-8") +" <br/>");
                }
             }else{
                 out.println(
                   "<h2 class=\"tutheader\">No Cookie founds</h2>");
             }
             out.println("</body>");
             out.println("</html>");
            }
    
        /**
         * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            doGet(request, response);
        }
    
    }
    

    其中,我们是通过遍历循环取出cookie的

    Cookie cookie = null;
    Cookie[] cookies = null;
    // 获取与该域相关的 Cookie 的数组
    cookies = request.getCookies();
    
    
    if( cookies != null ){
                out.println("<h2>Cookie 名称和值</h2>");
                for (int i = 0; i < cookies.length; i++){
                   cookie = cookies[i];
                   if((cookie.getName( )).compareTo("name") == 0 ){
                        cookie.setMaxAge(0);
                        response.addCookie(cookie);
                        out.print("已删除的 cookie:" + 
                                     cookie.getName( ) + "<br/>");
                   }
                   out.print("名称:" + cookie.getName( ) + ",");
                   out.print("值:" +  URLDecoder.decode(cookie.getValue(), "utf-8") +" <br/>");
                }
             }else{
                 out.println(
                   "<h2 class=\"tutheader\">No Cookie founds</h2>");
             }
    

    在这里插入图片描述

    通过 Servlet 删除 Cookie

    删除 Cookie 是非常简单的。如果您想删除一个 cookie,那么您只需要按照以下三个步骤进行:

    读取一个现有的 cookie,并把它存储在 Cookie 对象中。
    使用 setMaxAge() 方法设置 cookie 的年龄为零,来删除现有的 cookie。
    把这个 cookie 添加到响应头。
    

    Session

    HttpSession 对象

    除了上述的三种方式,Servlet 还提供了 HttpSession 接口,该接口提供了一种跨多个页面请求或访问网站时识别用户以及存储有关用户信息的方式。

    Servlet 容器使用这个接口来创建一个 HTTP 客户端和 HTTP 服务器之间的 session 会话。会话持续一个指定的时间段,跨多个连接或页面请求。

    您会通过调用 HttpServletRequest 的公共方法 getSession() 来获取 HttpSession 对象,如下所示:
    HttpSession session = request.getSession();

    方法描述
    public Object getAttribute(String name)该方法返回在该 session 会话中具有指定名称的对象,如果没有指定名称的对象,则返回 null。
    public Enumeration getAttributeNames()该方法返回 String 对象的枚举,String 对象包含所有绑定到该 session 会话的对象的名称。
    public long getCreationTime()该方法返回该 session 会话被创建的时间,自格林尼治标准时间 1970 年 1 月 1 日午夜算起,以毫秒为单位。
    public String getId()该方法返回一个包含分配给该 session 会话的唯一标识符的字符串。
    public long getLastAccessedTime()该方法返回客户端最后一次发送与该 session 会话相关的请求的时间自格林尼治标准时间 1970 年 1 月 1 日午夜算起,以毫秒为单位。
    public int getMaxInactiveInterval()该方法返回 Servlet 容器在客户端访问时保持 session 会话打开的最大时间间隔,以秒为单位。
    public void invalidate()该方法指示该 session 会话无效,并解除绑定到它上面的任何对象。
    public boolean isNew()如果客户端还不知道该 session 会话,或者如果客户选择不参入该 session 会话,则该方法返回 true。
    public void removeAttribute(String name)该方法将从该 session 会话移除指定名称的对象。
    public void setAttribute(String name, Object value)该方法使用指定的名称绑定一个对象到该 session 会话。
    public void setMaxInactiveInterval(int interval)该方法在 Servlet 容器指示该 session 会话无效之前,指定客户端请求之间的时间,以秒为单位。

    现在来剖析下实例

    @WebServlet("/SessionTrack")
    public class SessionTrack extends HttpServlet {
        private static final long serialVersionUID = 1L;
    
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
        {
            // 如果不存在 session 会话,则创建一个 session 对象
            HttpSession session = request.getSession(true);
            // 获取 session 创建时间
            Date createTime = new Date(session.getCreationTime());
            // 获取该网页的最后一次访问时间
            Date lastAccessTime = new Date(session.getLastAccessedTime());
             
            //设置日期输出的格式  
            SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
        	 //新建几个变量以及默认几个数据
            String title = "Servlet Session 实例 - 菜鸟教程";
            Integer visitCount = new Integer(0);
            String visitCountKey = new String("visitCount");
            String userIDKey = new String("userID");
            String userID = new String("Runoob");
            if(session.getAttribute(visitCountKey) == null) {
                session.setAttribute(visitCountKey, new Integer(0));
            }
    
        
            // 检查网页上是否有新的访问者
            if (session.isNew()){
                title = "Servlet Session 实例 - 菜鸟教程";
                 session.setAttribute(userIDKey, userID);//调用了setAttribute方法后直接可以将参数传入session对象中,然后只要out.println里面调用显示出来即可
            } else {
                 visitCount = (Integer)session.getAttribute(visitCountKey);
                 visitCount = visitCount + 1;
                 userID = (String)session.getAttribute(userIDKey);
            }
            session.setAttribute(visitCountKey,  visitCount);
        
            // 设置响应内容类型
            response.setContentType("text/html;charset=UTF-8");
            PrintWriter out = response.getWriter();
        
            String docType = "<!DOCTYPE html>\n";
            out.println(docType +
                    "<html>\n" +
                    "<head><title>" + title + "</title></head>\n" +
                    "<body bgcolor=\"#f0f0f0\">\n" +
                    "<h1 align=\"center\">" + title + "</h1>\n" +
                     "<h2 align=\"center\">Session 信息</h2>\n" +
                    "<table border=\"1\" align=\"center\">\n" +
                    "<tr bgcolor=\"#949494\">\n" +
                    "  <th>Session 信息</th><th>值</th></tr>\n" +
                    "<tr>\n" +
                    "  <td>id</td>\n" +
                    "  <td>" + session.getId() + "</td></tr>\n" +
                    "<tr>\n" +
                    "  <td>创建时间</td>\n" +
                    "  <td>" +  df.format(createTime) + 
                    "  </td></tr>\n" +
                    "<tr>\n" +
                    "  <td>最后访问时间</td>\n" +
                    "  <td>" + df.format(lastAccessTime) + 
                    "  </td></tr>\n" +
                    "<tr>\n" +
                    "  <td>用户 ID</td>\n" +
                    "  <td>" + userID + 
                    "  </td></tr>\n" +
                    "<tr>\n" +
                    "  <td>访问统计:</td>\n" +
                    "  <td>" + visitCount + "</td></tr>\n" +
                    "</table>\n" +
                    "</body></html>"); 
        }
    }
    

    在这里插入图片描述

    删除 Session 会话数据

    当您完成了一个用户的 session 会话数据,您有以下几种选择:

  • 移除一个特定的属性:您可以调用 public void removeAttribute(String name) 方法来删除与特定的键相关联的值。
  • 删除整个 session 会话:您可以调用 public void invalidate() 方法来丢弃整个 session 会话。
  • 设置 session 会话过期时间:您可以调用 public void setMaxInactiveInterval(int interval) 方法来单独设置 session 会话超时。
  • 注销用户:如果使用的是支持 servlet 2.4 的服务器,您可以调用 logout 来注销 Web 服务器的客户端,并把属于所有用户的所有 session 会话设置为无效。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值