首頁 Java java教程 Java中關於servlet之cookie的簡單介紹(圖文)

Java中關於servlet之cookie的簡單介紹(圖文)

Jul 26, 2017 pm 03:06 PM
cookie java servlet

Cookie技術誕生以來,它就成了廣大網路使用者和Web開發人員爭論的一個焦點。以下這篇文章主要為大家介紹了關於servlet之cookie簡介的相關資料,文中介紹的非常詳細,需要的朋友可以參考借鑒,下面來一起看看吧。

  首先來了解什麼是「會話」。會話是web技術中的一個術語,可以簡單的理解為:用戶打開一個瀏覽器,點擊多個超鏈接,訪問伺服器多個web資源,然後關閉瀏覽器,這個過程稱為一個會話。

  如果在開啟一個瀏覽器造訪一個頁面後,再開啟一個瀏覽器造訪同一個頁面,那麼這就是有兩個會話;而開啟一個瀏覽器造訪一個頁面後,透過這個頁面上的某個超連結是從新的瀏覽器開啟的,那依然只算一個會話。

  每個使用者在使用瀏覽器與伺服器進行會話的過程中,各自不可避免地會產生一些數據,而程式要想辦法為每個使用者保存這些資料。例如,用戶點擊超連結透過一個產品Servlet購買了一個商品,程式應該想辦法保存這個商品,以便於用戶在點擊付款超連結時能再從付款Servlet中看到這個商品並為其買單。

  使用Request對像是無法保存資料的,因為在點擊商品和付款各自的Servlet是發送兩個不同的Request請求對象,而使用ServletContext對象則會發生多個用戶的線程安全問題,使用轉發功能理論上可行,但使用者體驗將會大打折扣,每次點擊一個商品就會被要求付款。所以根據以上的需求,有兩種技術來保存會話過程中產生的資料:一個是Cookie,一個是Session,Session技術將會在之後的篇章中介紹學習。

  本篇主要先講述Servlet中的Cookie技術。 Cookie技術是客戶端技術,程式把每個使用者的資料以cookie的形式寫給使用者各自的瀏覽器。當使用者使用瀏覽器再去存取伺服器時,就會帶著各自的資料過去,這樣web伺服器處理的就是使用者各自的資料了。

下圖是一個會話過程中設定上一次存取時間的Cookie的簡單過程:

#  

建立一個Cookie物件就像平常會建立一個Java對象一樣簡單:

  

在使用建構器時傳入Cookie的名稱和值這樣的鍵值對即可,我們在伺服器端要取得從瀏覽器發送的Cookie資料可以使用請求物件的request.getCookies方法來取得一個Cookie數組,而我們想向瀏覽器輸出Cookie時可以使用回應物件的response.addCookie(Cookie)方法。

同時Cookie物件還有以下一些方法:

  

#  getName方法用來取得某個Cookie物件的名稱。

  setValue方法和getValue方法分別用來設定和取得某個Cookie物件的值。

  setMaxAge(int expires)方法是設定Cookie的有效期限,如果沒有這句程式碼,Cookie的有效期限就是一個會話時間(即關閉瀏覽器該Cookie就不存在了),當設定了Cookie的有效期限後,Cookie會保存在瀏覽器指定的硬碟檔案中,同時在這段時間內,每次存取伺服器都會帶著Cookie過去。如果將該方法參數置為“0”,則伺服器會指示瀏覽器刪除該Cookie。

  setPath方法是設定Cookie的有效路徑。表示在存取某些特定URL時才會帶Cookie過去。假設某個web應用為【myservlet】,如果我們將setPath方法中的參數設為“/myservlet”,那麼訪問該web應用下所有的資源都會使瀏覽器發送Cookie過去;而如果我們將setPath方法中的參數設定為“/myservlet/pages”,那麼只有存取該web應用程式中的【pages】下的資源才會帶Cookie過去,而存取該web應用程式中的其他資源則不會帶Cookie給伺服器。如果我們沒有設定setPath方法,那麼該Cookie的有效路徑預設為建立Cookie物件的目前程式所在目錄。請注意,Cookie的路徑是給瀏覽器使用的(詳見《Servlet的學習之web路徑問題》)

  setDomain方法是設定Cookie的有效域名,如:.sina.com(注意最前面有一個點)。表示當瀏覽器造訪該網域時才會帶Cookie過去。但是現在瀏覽器基本上全面阻止了這個可能作為不安全的功能,所以幾乎已經被棄用。 

  举例:我们访问某个Servlet,而在访问这个Servlet时会将当前访问时间作为Cookie中的值返回给客户端,同时下次再次访问该Servlet时,会显示上一次客户端来访问的时间:


public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  
  response.setCharacterEncoding("UTF-8");
  response.setContentType("text/html;charset=utf-8");
  
  PrintWriter writer = response.getWriter();
  writer.write("您上次访问的时间是:");
  //获取用户上一次的访问时间并显示
  Cookie[] cookies = request.getCookies();   //从请求中获取客户端发来的Cookie
  for(int i=0;cookies!=null && i<cookies.length;i++) {
   if(cookies[i].getName().equals("lastAccessTime")) { //获取最后访问时间的Cookie
    Long mTime = Long.parseLong(cookies[i].getValue());  
    String lastAccessTime = new Date(mTime).toLocaleString();
    writer.write(lastAccessTime);
   }
  }
  //将本次登录时间重新装载进Cookie中并返回给客户端
  Cookie timeCookie = new Cookie("lastAccessTime", System.currentTimeMillis()+"");
  timeCookie.setMaxAge(1*24*60*60); //将Cookie有效期置为一天
  response.addCookie(timeCookie);  //将Cookie传回客户端
 }
登入後複製

第一次访问是没有Cookie的,所以看不到访问时间:

  

但是我们通过HttpWatch观察Response响应包中的内容已经有了“Set-Cookie”响应头:

  

刷新后的第二次访问就可以看到了:

  

同时观察HttpWatch中Request请求包的“Cookie”请求头可以发现:

  

  现在我们再来通过一个案例来学习Cookie,这是一个很常见的案例,比如我们在访问购物网站的时候经常会发现当浏览了这个网站内的某个商品的时候,下次继续来访问这个网站,会有一个上次浏览物品的显示。

  如果我们不是用登录后将记录保存在服务器端,而是使用Cookie技术来将记录保存在客户端的浏览器中(现实生活中当然很少这样使用,这里只是作为案例学习),那么我们应该怎么做呢?

  首先我们必须在服务器要有两个Servlet,一个在用户眼中是用来显示所有商品的,一个是用来显示点击某个商品之后详细信息的。

  ⑴.用来显示所有商品的Servlet需要完成如下功能:

   ① 在一个部分以超链接形式将数据库中所有的商品显示在该Servlet上。

   ② 在另一个部分获取用户请求中的Cookie将之前浏览过的商品(通过Cookie中的商品id)显示在该Servlet上。

  ⑵. 用来显示点击某个商品之后详细信息的Servlet需要完成如下功能:

   ① 在页面上通过超链接的URL跟随的参数(即商品id)来获取该商品对象,同时将该商品对象的详细信息输出到Servlet页面上。

   ② 如果是用户首次访问,将用户浏览商品的id作为Cookie直接返回,而如果是用户再次访问,则需要根据一定的条件来将这些Cookie的值进行调整,以便易于显示和满足用户体验。

  当然,在这之前我们还需要做些准备工作,我们需要建立商品对象,这里简单的以书为商品建立对象:


public class Product {
 
 private String id;
 private String name;
 private String author;
 
 public Product() {
  super();
  
 }
 public Product(String id, String name, String author) {
  super();
  this.id = id;
  this.name = name;
  this.author = author;
 }
 
 public String getId() {
  return id;
 }
 public void setId(String id) {
  this.id = id;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public String getAuthor() {
  return author;
 }
 public void setAuthor(String author) {
  this.author = author;
 }
}
登入後複製

我们还需要一个数据库来保存商品,这里我们先用一个类来来保存(数据库还没学嘛T_T!),保存数据采用Map集合,这是因为如果有检索会方便:


public class ProductDatabase {
 
 private static Map<String,Product> map = new HashMap<String, Product>();
 
 static{
  map.put("1", new Product("1","《Java编程思想》","JB"));
  map.put("2", new Product("2","《Java核心技术》","fdaf"));
  map.put("3", new Product("3","《Java并发编程》","什么鬼"));
  map.put("4", new Product("4","《Head first 设计模式》","老王"));
  map.put("5", new Product("5","《HTML5权威手册》","hhaa"));
 }
 
 public static Map<String,Product> getMap() {
 
  return map;
 }
 
}
登入後複製

做完了这两步,那么我们可以安心的去搞Servlet了,首先是在显示所有商品的Servlet:


response.setCharacterEncoding("UTF-8");
  response.setContentType("text/html;charset=utf-8");
  
  PrintWriter writer = response.getWriter();
  //从数据库中取出要显示在购物网站首页的商品
  Map<String,Product> map = ProductDatabase.getMap();
  if(map == null) {
   writer.print("您访问的宝贝已下架");
   return ;
  }
  for(Map.Entry<String, Product> en : map.entrySet()) {
   writer.print("<a href=&#39;/CookieProductProject/servlet/DetailGoodServlet?id="+en.getKey()+"&#39; target=&#39;_blank&#39; >"
              +en.getValue().getName()+" <br/>");
  }
  
  
  //显示用户之前浏览过的商品,要从用户发送的请求中的Cookie里取得
  writer.print("<br/><br/>");
  writer.print("您最近浏览过的商品: <br/>");
  
  Cookie[] cookies = request.getCookies();
  for(int i=0;cookies!=null && i<cookies.length;i++ ) {
   if(cookies[i].getName().equals("productHistory")) {
    Cookie cookie = cookies[i];
    String productId = cookie.getValue();
    String[] splitId = productId.split("\\_");
    for(String sId:splitId) {
     Product book = ProductDatabase.getMap().get(sId);
     writer.print(book.getName()+"<br/>");
    }
   }
  }
}
登入後複製

最后是点击某个商品显示详细信息的Servlet:


response.setCharacterEncoding("UTF-8");
  response.setContentType("text/html;charset=UTF-8");
  PrintWriter writer = response.getWriter();

  //通过用户点击商品的超链接而跟随URL来的ID参数来获取商品的详细信息
  String productId = request.getParameter("id");
  Map<String, Product> map = ProductDatabase.getMap();
  Product book = map.get(productId);
  writer.print("商品名:"+book.getName()+"<br />");
  writer.print("作者:"+book.getAuthor());
  
  //同时通过Cookie将用户观看的商品以Cookie的形式回传给用户浏览器 
  Cookie[] allCookies = request.getCookies();
  
  Cookie cookie = creCookie(book.getId(),allCookies);
  cookie.setMaxAge(24*60*60);
  response.addCookie(cookie);
登入後複製

其中creCookie(String,Cookie[])是自定义方法,用于获取用户的cookie并添加本次浏览商品id再作为cookie返回:


private Cookie creCookie(String id, Cookie[] cookies) {
  Cookie cookie = null;
  
  if(cookies == null) { //如果cookies为空,说明用户首次访问
   cookie = new Cookie("productHistory", id);
   System.out.println(cookie.getValue());
   return cookie;
  }
  for(int i=0; i<cookies.length; i++) {
   if(cookies[i].getName().equals("productHistory")){
    cookie = cookies[i];
   }
  }
  
  String historyStr = cookie.getValue(); //此时获取到的之前浏览过数据的历史记录,有多种情况
  String[] produIds = historyStr.split("\\_");
  
  //为了检测数组中是否有包含当前的id,建议使用集合,而且是使用链表结构的集合
  LinkedList<String> list = new LinkedList<String>(Arrays.asList(produIds));
  if(list.contains(id)) {
   list.remove(id);
  }
  else if(list.size()>=3){
    list.removeLast();
  }
  
  list.addFirst(id);
  
  StringBuilder sb = new StringBuilder();
  for(String sId :list) {
   sb.append(sId+"_");
  }
  sb.deleteCharAt(sb.length()-1); 
  cookie.setValue(sb.toString());
  System.out.println(cookie.getValue());
  return cookie;
}
登入後複製

我们在浏览器中进行首次访问:

  

随便点击个连接,可以看到该商品的详细信息(其实浏览器也偷偷将该商品的id以cookie传回了浏览器):

  

我们访问商品显示页面再次【刷新】就可以看到刚才浏览过的商品了:

  

总结

以上是Java中關於servlet之cookie的簡單介紹(圖文)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

突破或從Java 8流返回? 突破或從Java 8流返回? Feb 07, 2025 pm 12:09 PM

Java 8引入了Stream API,提供了一種強大且表達力豐富的處理數據集合的方式。然而,使用Stream時,一個常見問題是:如何從forEach操作中中斷或返回? 傳統循環允許提前中斷或返回,但Stream的forEach方法並不直接支持這種方式。本文將解釋原因,並探討在Stream處理系統中實現提前終止的替代方法。 延伸閱讀: Java Stream API改進 理解Stream forEach forEach方法是一個終端操作,它對Stream中的每個元素執行一個操作。它的設計意圖是處

PHP:網絡開發的關鍵語言 PHP:網絡開發的關鍵語言 Apr 13, 2025 am 12:08 AM

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP與Python:了解差異 PHP與Python:了解差異 Apr 11, 2025 am 12:15 AM

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

Java程序查找膠囊的體積 Java程序查找膠囊的體積 Feb 07, 2025 am 11:37 AM

膠囊是一種三維幾何圖形,由一個圓柱體和兩端各一個半球體組成。膠囊的體積可以通過將圓柱體的體積和兩端半球體的體積相加來計算。本教程將討論如何使用不同的方法在Java中計算給定膠囊的體積。 膠囊體積公式 膠囊體積的公式如下: 膠囊體積 = 圓柱體體積 兩個半球體體積 其中, r: 半球體的半徑。 h: 圓柱體的高度(不包括半球體)。 例子 1 輸入 半徑 = 5 單位 高度 = 10 單位 輸出 體積 = 1570.8 立方單位 解釋 使用公式計算體積: 體積 = π × r2 × h (4

PHP與其他語言:比較 PHP與其他語言:比較 Apr 13, 2025 am 12:19 AM

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

PHP與Python:核心功能 PHP與Python:核心功能 Apr 13, 2025 am 12:16 AM

PHP和Python各有優勢,適合不同場景。 1.PHP適用於web開發,提供內置web服務器和豐富函數庫。 2.Python適合數據科學和機器學習,語法簡潔且有強大標準庫。選擇時應根據項目需求決定。

創造未來:零基礎的 Java 編程 創造未來:零基礎的 Java 編程 Oct 13, 2024 pm 01:32 PM

Java是熱門程式語言,適合初學者和經驗豐富的開發者學習。本教學從基礎概念出發,逐步深入解說進階主題。安裝Java開發工具包後,可透過建立簡單的「Hello,World!」程式來實踐程式設計。理解程式碼後,使用命令提示字元編譯並執行程序,控制台上將輸出「Hello,World!」。學習Java開啟了程式設計之旅,隨著掌握程度加深,可創建更複雜的應用程式。

PHP:許多網站的基礎 PHP:許多網站的基礎 Apr 13, 2025 am 12:07 AM

PHP成為許多網站首選技術棧的原因包括其易用性、強大社區支持和廣泛應用。 1)易於學習和使用,適合初學者。 2)擁有龐大的開發者社區,資源豐富。 3)廣泛應用於WordPress、Drupal等平台。 4)與Web服務器緊密集成,簡化開發部署。

See all articles