隨筆-71  評論-4  文章-0  trackbacks-0
          一、 Cookie概述
             Cookie是服務(wù)器發(fā)送給瀏覽器的體積很小的純文本信息,用戶以后訪問同一個Web服務(wù)器時瀏覽器會把它們原樣發(fā)送給服務(wù)器。通過讓服務(wù)器讀取它原先保存到客戶端的信息,網(wǎng)站能夠為瀏覽者提供一系列的方便,例如在線交易過程中標(biāo)識用戶身份、安全要求不高的場合避免用戶重復(fù)輸入名字和密碼、門戶網(wǎng)站的主頁定制、有針對性地投放廣告,等等。

             Cookie的目的就是為用戶帶來方便,為網(wǎng)站帶來增值。雖然有著許多誤傳,事實上Cookie并不會造成嚴(yán)重的安全威脅。Cookie永遠不會以任何方式執(zhí)行,因此也不會帶來病毒或攻擊你的系統(tǒng)。另外,由于瀏覽器一般只允許存放300個Cookie,每個站點最多存放20個Cookie,每個 Cookie的大小限制為4 KB,因此Cookie不會塞滿你的硬盤,更不會被用作“拒絕服務(wù)”攻擊手段。



          二、 Servlet的Cookie API

             要把Cookie發(fā)送到客戶端,Servlet先要調(diào)用new Cookie(name,value)用合適的名字和值創(chuàng)建一個或多個Cookie,通過cookie.setXXX設(shè)置各種屬性,通過response.addCookie(cookie)把cookie加入應(yīng)答頭。

             要從客戶端讀入Cookie,Servlet應(yīng)該調(diào)用request.getCookies(),getCookies()方法返回一個Cookie對象的數(shù)組。在大多數(shù)情況下,你只需要用循環(huán)訪問該數(shù)組的各個元素尋找指定名字的Cookie,然后對該Cookie調(diào)用getValue方法取得與指定名字關(guān)聯(lián)的值。

          三、 創(chuàng)建Cookie

             調(diào)用Cookie對象的構(gòu)造函數(shù)可以創(chuàng)建Cookie。Cookie對象的構(gòu)造函數(shù)有兩個字符串參數(shù):Cookie名字和Cookie值。名字和值都不能包含空白字符以及下列字符:
          [ ] ( ) = , " / ? @ : ;


          四、 讀取和設(shè)置Cookie屬性

             把Cookie加入待發(fā)送的應(yīng)答頭之前,你可以查看或設(shè)置Cookie的各種屬性。下面摘要介紹這些方法:

          getComment/setComment
               獲取/設(shè)置Cookie的注釋。

          getDomain/setDomain
               獲取/設(shè)置Cookie適用的域。一般地,Cookie只返回給與發(fā)送它的服務(wù)器名字完全相同的服務(wù)器。使用這里的方法可以指示瀏覽器把Cookie返回給同一域內(nèi)的其他服務(wù)器。注意域必須以點開始(例如.sitename.com),非國家類的域(如.com,.edu,.gov)必須包含兩個點,國家類的域(如.com.cn,.edu.uk)必須包含三個點。

          getMaxAge/setMaxAge
               獲取/設(shè)置Cookie過期之前的時間,以秒計。如果不設(shè)置該值,則Cookie只在當(dāng)前會話內(nèi)有效,即在用戶關(guān)閉瀏覽器之前有效,而且這些Cookie不會保存到磁盤上。參見下面有關(guān)LongLivedCookie的說明。

          getName/setName
               獲取/設(shè)置Cookie的名字。本質(zhì)上,名字和值是我們始終關(guān)心的兩個部分。由于HttpServletRequest的getCookies方法返回的是一個Cookie對象的數(shù)組,因此通常要用循環(huán)來訪問這個數(shù)組查找特定名字,然后用getValue檢查它的值。

          getPath/setPath
               獲取/設(shè)置Cookie適用的路徑。如果不指定路徑,Cookie將返回給當(dāng)前頁面所在目錄及其子目錄下的所有頁面。這里的方法可以用來設(shè)定一些更一般的條件。例如,someCookie.setPath("/"),此時服務(wù)器上的所有頁面都可以接收到該Cookie。

          getSecure/setSecure
              獲取/設(shè)置一個boolean值,該值表示是否Cookie只能通過加密的連接(即SSL)發(fā)送。

          getValue/setValue
              獲取/設(shè)置Cookie的值。如前所述,名字和值實際上是我們始終關(guān)心的兩個方面。不過也有一些例外情況,比如把名字作為邏輯標(biāo)記(也就是說,如果名字存在,則表示true)。

          getVersion/setVersion
               獲取/設(shè)置Cookie所遵從的協(xié)議版本。默認(rèn)版本0(遵從原先的Netscape規(guī)范);版本1遵從RFC 2109 , 但尚未得到廣泛的支持。

          五、 在應(yīng)答頭中設(shè)置Cookie

             Cookie可以通過HttpServletResponse的addCookie方法加入到Set-Cookie應(yīng)答頭。下面是一個例子:

          Cookie userCookie = new Cookie("user", "uid1234");
          response.addCookie(userCookie);




          六、 讀取保存到客戶端的Cookie

             要把Cookie發(fā)送到客戶端,先要創(chuàng)建Cookie,然后用addCookie發(fā)送一個Set-Cookie HTTP應(yīng)答頭。這些內(nèi)容已經(jīng)在上面介紹。從客戶端讀取Cookie時調(diào)用的是HttpServletRequest的getCookies方法。該方法返回一個與HTTP請求頭中的內(nèi)容對應(yīng)的Cookie對象數(shù)組。得到這個數(shù)組之后,一般是用循環(huán)訪問其中的各個元素,調(diào)用getName檢查各個Cookie的名字,直至找到目標(biāo)Cookie。然后對這個目標(biāo)Cookie調(diào)用getValue,根據(jù)獲得的結(jié)果進行其他處理。

             上述處理過程經(jīng)常會遇到,為方便計下面我們提供一個getCookieValue方法。只要給出Cookie對象數(shù)組、Cookie名字和默認(rèn)值, getCookieValue方法就會返回匹配指定名字的Cookie值,如果找不到指定Cookie,則返回默認(rèn)值。

          七、幾個Cookie工具函數(shù)

             下面是幾個工具函數(shù)。這些函數(shù)雖然簡單,但是,在和Cookie打交道的時候很有用。

             1、 獲取指定名字的Cookie值

             getCookieValue通過循環(huán)依次訪問Cookie對象數(shù)組的各個元素,尋找是否有指定名字的Cookie,如找到,則返回該Cookie的值;否則,返回參數(shù)中給出的默認(rèn)值。getCookieValue能夠在一定程度上簡化 Cookie值的提取。

          public static String getCookieValue(Cookie[] cookies, String cookieName, String defaultValue) {
             for(int i=0; i<cookies.length; i++) {
               Cookie cookie = cookies[i];
               if (cookieName.equals(cookie.getName()))
                 return(cookie.getValue());
              }
              return(defaultValue);
          }




             2、自動保存的Cookie

             下面是LongLivedCookie類的代碼。如果你希望Cookie能夠在瀏覽器退出的時候自動保存下來,則可以用這個LongLivedCookie類來取代標(biāo)準(zhǔn)的Cookie類。

          package hall;
          import javax.servlet.http.*;

          public class LongLivedCookie extends Cookie {
             public static final int SECONDS_PER_YEAR = 60*60*24*365;
             public LongLivedCookie(String name, String value) {
               super(name, value);
               setMaxAge(SECONDS_PER_YEAR);
             }
          }


          八、實例:定制的搜索引擎界面

             下面是一個搜索引擎界面的例子,在這個Servlet中,用戶界面是動態(tài)生成而不是由靜態(tài)HTML文件提供的。Servlet除了負責(zé)讀取表單數(shù)據(jù)并把它們發(fā)送給搜索引擎之外,還要把包含表單數(shù)據(jù)的Cookie發(fā)送給客戶端。以后客戶再次訪問同一表單時,這些 Cookie的值將用來預(yù)先填充表單,使表單自動顯示最近使用過的數(shù)據(jù)。

             SearchEnginesFrontEnd.java

             該Servlet構(gòu)造一個主要由表單構(gòu)成的用戶界面。第一次顯示的時候,它和靜態(tài)HTML頁面提供的界面差不多。然而,用戶選擇的值將被保存到 Cookie(本頁面將數(shù)據(jù)發(fā)送到CustomizedSearchEngines Servlet,由后者設(shè)置Cookie)。用戶以后再訪問同一頁面時,即使瀏覽器是退出之后再啟動,表單中也會自動填好上一次搜索所填寫的內(nèi)容。

             注意該Servlet用到了ServletUtilities.java,其中g(shù)etCookieValue前面已經(jīng)介紹過,headWithTitle 用于生成HTML頁面的一部分。另外,這里也用到了前面已經(jīng)說明的LongLiveCookie類,我們用它來創(chuàng)建作廢期限很長的Cookie。
          package hall;

          import java.io.*;
          import javax.servlet.*;
          import javax.servlet.http.*;
          import java.net.*;

          public class SearchEnginesFrontEnd extends HttpServlet {
            public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              Cookie[] cookies = request.getCookies();
              String searchString =getCookieValue(cookies, "searchString", "Java Programming");
              String numResults = getCookieValue(cookies, "numResults", "10");
              String searchEngine =getCookieValue(cookies, "searchEngine", "google");
              response.setContentType("text/html");
              PrintWriter out = response.getWriter();
              String title = "Searching the Web";
              out.println("<BODY BGCOLOR=\"#FDF5E6\">\n" +
                "<H1 ALIGN=\"CENTER\">Searching the Web</H1>\n" +
                "\n" +
                "<FORM ACTION=\"/servlet/hall.CustomizedSearchEngines\">\n" +
                "<CENTER>\n" +
                "Search String:\n" +
                "<INPUT TYPE=\"TEXT\" NAME=\"searchString\"\n" +
                " VALUE=\"" + searchString + "\"><BR>\n" +
                "Results to Show Per Page:\n" +
                "<INPUT TYPE=\"TEXT\" NAME=\"numResults\"\n" +
                " VALUE=" + numResults + " SIZE=3><BR>\n" +
                "<INPUT TYPE=\"RADIO\" NAME=\"searchEngine\"\n" +
                " VALUE=\"google\"" +
                checked("google", searchEngine) + ">\n" +
                "Google |\n" +
                "<INPUT TYPE=\"RADIO\" NAME=\"searchEngine\"\n" +
                " VALUE=\"infoseek\"" +
                checked("infoseek", searchEngine) + ">\n" +
                "Infoseek |\n" +
                "<INPUT TYPE=\"RADIO\" NAME=\"searchEngine\"\n" +
                " VALUE=\"lycos\"" +
                 checked("lycos", searchEngine) + ">\n" +
                "Lycos |\n" +
                "<INPUT TYPE=\"RADIO\" NAME=\"searchEngine\"\n" +
                " VALUE=\"hotbot\"" +
                checked("hotbot", searchEngine) + ">\n" +
                "HotBot\n" +
                "<BR>\n" +
                "<INPUT TYPE=\"SUBMIT\" VALUE=\"Search\">\n" +
                "</CENTER>\n" +
                "</FORM>\n" +
                "\n" +
                "</BODY>\n" +
                "</HTML>\n");
              }

              private String checked(String name1, String name2) {
                 if (name1.equals(name2))
                     return(" CHECKED");
                 else
                     return("");
              }

           public String getCookieValue(Cookie[] cookies, String cookieName, String defaultValue) {
             for(int i=0; i<cookies.length; i++) {
               Cookie cookie = cookies[i];
               if (cookieName.equals(cookie.getName()))
                 return(cookie.getValue());
              }
              return(defaultValue);
          }


          }




             CustomizedSearchEngines.java

             前面的SearchEnginesFrontEnd Servlet把數(shù)據(jù)發(fā)送到CustomizedSearchEngines Servlet,下面例子除了要構(gòu)造一個針對搜索引擎的URL并向用戶發(fā)送一個重定向應(yīng)答之外,還要發(fā)送保存用戶數(shù)據(jù)的Cookies。

          package hall;
          
          import java.io.*;
          import javax.servlet.*;
          import javax.servlet.http.*;
          import java.net.*;
          
          public class CustomizedSearchEngines extends HttpServlet {
           public void doPost(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException{
          
            String searchString = request.getParameter("searchString");
            Cookie searchStringCookie =new LongLivedCookie("searchString", searchString);
            response.addCookie(searchStringCookie);
            //searchString = URLEncoder.encode(searchString);
          
            String numResults = request.getParameter("numResults");
            Cookie numResultsCookie =new LongLivedCookie("numResults", numResults);
            response.addCookie(numResultsCookie);
            String searchEngine = request.getParameter("searchEngine");
            Cookie searchEngineCookie =new LongLivedCookie("searchEngine", searchEngine);
            response.addCookie(searchEngineCookie);
            String url=request.getContextPath()+"/index.jsp";
                      url=response.encodeRedirectURL(url);
          
          
            //這里用這個url代替了google搜索
           response.sendRedirect(url);
             
           
          }
          
          } 
          
          

          這個應(yīng)用的運行圖:(用戶的輸入數(shù)據(jù)瀏覽器下次啟動時將會保留)


          posted on 2006-01-12 12:25 zjw_albert 閱讀(103) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 大英县| 阳曲县| 乌拉特后旗| 图片| 嵊泗县| 永仁县| 吴堡县| 江陵县| 句容市| 楚雄市| 鄂托克旗| 濉溪县| 夹江县| 龙川县| 乌鲁木齐县| 梅河口市| 荆州市| 元阳县| 咸宁市| 罗甸县| 肇东市| 沙河市| 德令哈市| 台中县| 双牌县| 连城县| 阿克苏市| 博乐市| 天全县| 高平市| 修文县| 宜昌市| 册亨县| 临江市| 屏南县| 玉林市| 墨玉县| 睢宁县| 贵阳市| 尉犁县| 丹凤县|