会话跟踪

    要实现由状态的会话,就需要在Web服务器程序和客户端浏览器之间来回传递会话ID,以关联同一客户端浏览器向Web服务器程序发出的连续请求。实现在Web服务器程序和客户端浏览器之间来回传递会话ID的技术称为会话跟踪技术。会话跟踪技术主要有两种:一种是通过Cookie技术在请求消息首部中传递会话ID;另一种是通过URL重写,即在URL的末尾添上这个会话ID。

1、Cookie技术
    Cookie是在浏览器访问Web服务器的某个资源时,由Web服务器再HTTP响应消息头中附带传送给浏览器的一段数据。浏览器可以决定是否保存这段数据。一旦浏览器保存了这段数据,那么它在以后每次访问该Web服务器时,都会在HTTP请求头中将这段数据传回给Web服务器。很显然,Cookie最先是由Web服务器发出的,是否发送Cookie和发送的Cookie的具体内容,完全由Web服务器端程序决定。
    Web服务器程序是通过在HTTP响应消息头中增加Set-Cookie字段将Cookie信息发送给浏览器的,浏览器则通过在HTTP请求消息头中增加Cookie字段将Cookie信息回传给Web服务器。
    在Servlet类中操作Cookie:
    · public Cookie(String name, String value):Cookie类中提供的一个构造方法,用来创建Cookie实例,name用来指定Cookie的名称,value用来指定它的值。
    · getName():用来获取该Cookie的名称。
    · setValue()和getValue():用来设置和获取CookieCookie的值。
    · setMaxAge()和getMaxAge():用来设置和获取Cookie在客户端浏览器上保持有效的时间秒值。
    · setPath()和getPath():用于设置和获取Cookie的有效目录路径。
    · setDomain()和getDomain():用于设置和获取Cookie的有效域。
    如果想把一个构造好的Cookie实例的消息添加到响应消息头中,可以使用HttpServletResponse接口中提供的addCookie()方法。如果有多个Cookie实例消息要添加到响应消息头中,可以多次调用这个方法。相反,如果想从HTTP请求消息头中读取所有的Cookie信息,可以使用HttpServletRequest接口中提供的getCookies()方法,这个方法会读取该请求消息头中的所有Cookie消息,并封装成各个    Cookie实例,存储在一个数组中再返回。遍历这个cookie数组,就可以获取想要的Cookie信息了。
    Servlet类,在它的请求处理方法中往响应中写入Cookie信息,同时还从用户的这个请求消息中获取当前所有的Cookie信息。
package com.yyq.cookies;
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;
/**
 * Created by gao on 16-4-14.
 */
public class CookieServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //创建一个Cookie实例
        Cookie cookie = new Cookie("username", "yuqin");
        //设置有效时间为1天
        cookie.setMaxAge(24 * 3600);
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter out = resp.getWriter();
        //往响应中写入Cookie
        resp.addCookie(cookie);
        //获取Cookie数组
        Cookie[] cookies = req.getCookies();
        if (null == cookies) {
            out.println("<h3>还没有Cookie</h3>");
        } else {
            out.println("<h3>Cookie列表</h3>");
            //遍历Cookie信息
            for (int i = 0; i < cookies.length; i++) {
                out.print("Cookie名称:" + cookies[i].getName());
                out.println(",对应的值为:" + cookies[i].getValue());
                out.println("<br />");
            }
        }
    }
    @Override
    public void destroy() {
        //
    }
    @Override
    public void init() throws ServletException {
        //
    }
}

 web.xml注册:

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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_3_0.xsd"
           version="3.0">
 <!--CookieServlet的配置-->
    <servlet>
        <servlet-name>cookieservlet</servlet-name>
        <servlet-class>com.yyq.cookies.CookieServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>cookieservlet</servlet-name>
        <url-pattern>/cookieservlet</url-pattern>
    </servlet-mapping>
</web-app>

 

2、Session技术
    为了在服务器端保存用户会话的状态信息,Servlet API规范中提供了一个javax.serlvet.http.HttpSession接口,这个接口中定义了各种管理和操作会话状态的方法。一个客户端在Web服务器端对应一个各自的HttpSession实例。Web容器并不在每个客户端第一次访问时就自动创建HttpSession实例。只有客户端访问某个编写了创建HttpSession实例代码的Servlet时,才会创建一个HttpSession实例,Web容器创建这个HttpSession实例时,会为它分配一个独一无二的会话ID,再返回响应给客户端时会在响应消息中把这个会话ID以Cookie的方式传递给客户端。客户端需要记住这个会话ID,并在后续的每次访问请求中都带上这个会话ID,传回给Web服务器,Web服务器程序会根据传回的会话ID找到对应的HttpSession实例。
    1)创建HttpSession实例
    · public HttpSession getSession():调用此方法时,容器会先检查客户端先前送出的请求是否建立过HTTP会话;如果没有,容器会新建一个会话,并赋予一个唯一的会话ID;如果有,容器会根据客户请求中的会话ID找到相匹配的会话。
    · public HttpSession getSession(boolean flag):此方法的flag参数用来指定是否有必要创建一个会话,调用getSession(false)时,若客户先前没有建立过会话,则方法将返回null。
    2)Session的常用操作
序号方法 & 描述
1 public Object getAttribute(String name)
该方法返回在该 session 会话中具有指定名称的对象,如果没有指定名称的对象,则返回 null。
2 public Enumeration getAttributeNames()
该方法返回 String 对象的枚举,String 对象包含所有绑定到该 session 会话的对象的名称。
3 public long getCreationTime()
该方法返回该 session 会话被创建的时间,自格林尼治标准时间 1970 年 1 月 1 日午夜算起,以毫秒为单位。
4 public String getId()
该方法返回一个包含分配给该 session 会话的唯一标识符的字符串。
5 public long getLastAccessedTime()
该方法返回客户端最后一次发送与该 session 会话相关的请求的时间自格林尼治标准时间 1970 年 1 月 1 日午夜算起,以毫秒为单位。
6 public int getMaxInactiveInterval()
该方法返回 Servlet 容器在客户端访问时保持 session 会话打开的最大时间间隔,以秒为单位。
7 public void invalidate()
该方法指示该 session 会话无效,并解除绑定到它上面的任何对象。
8 public boolean isNew(
如果客户端还不知道该 session 会话,或者如果客户选择不参入该 session 会话,则该方法返回 true。
9 public void removeAttribute(String name)
该方法将从该 session 会话移除指定名称的对象。
10 public void setAttribute(String name, Object value) 
该方法使用指定的名称绑定一个对象到该 session 会话。
11 public void setMaxInactiveInterval(int interval)
该方法在 Servlet 容器指示该 session 会话无效之前,指定客户端请求之间的时间,以秒为单位。
 
package com.yyq.session;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
/**
 * Created by gao on 16-4-24.
 */
public class SessionServlet extends HttpServlet {
    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());
        String title = "Session例子";
        Integer visitCount = new Integer(0);
        String visitCountKey = new String("visitCount");
        String userIDKey = new String("userID");
        String userID = new String("ABCD");
        // 检查网页上是否有新的访问者
        if (session.isNew()){
            title = "Session例子";
            session.setAttribute(userIDKey, userID);
        } else {
            visitCount = (Integer)session.getAttribute(visitCountKey);
            visitCount = visitCount + 1;
            userID = (String)session.getAttribute(userIDKey);
        }
        session.setAttribute(visitCountKey,  visitCount);
        // 设置响应内容类型
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        String docType =
                "<!doctype html public \"-//w3c//dtd html 4.0 " +
                        "transitional//en\">\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>Creation Time</td>\n" +
                "  <td>" + createTime +
                "  </td></tr>\n" +
                "<tr>\n" +
                "  <td>Time of Last Access</td>\n" +
                "  <td>" + lastAccessTime +
                "  </td></tr>\n" +
                "<tr>\n" +
                "  <td>User ID</td>\n" +
                "  <td>" + userID +
                "  </td></tr>\n" +
                "<tr>\n" +
                "  <td>Number of visits</td>\n" +
                "  <td>" + visitCount + "</td></tr>\n" +
                "</table>\n" +
                "</body></html>");
    }
}

 

posted @ 2016-04-24 15:27  我是一名老菜鸟  阅读(422)  评论(0编辑  收藏  举报