欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

servlet之cookie簡(jiǎn)介_(kāi)動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

 更新時(shí)間:2017年07月26日 10:37:27   作者:fjdingsd  
Cookie技術(shù)誕生以來(lái),它就成了廣大網(wǎng)絡(luò)用戶(hù)和Web開(kāi)發(fā)人員爭(zhēng)論的一個(gè)焦點(diǎn)。下面這篇文章主要給大家介紹了關(guān)于servlet之cookie簡(jiǎn)介的相關(guān)資料,文中介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。

  首先來(lái)了解什么是“會(huì)話(huà)”。會(huì)話(huà)是web技術(shù)中的一個(gè)術(shù)語(yǔ),可以簡(jiǎn)單的理解為:用戶(hù)打開(kāi)一個(gè)瀏覽器,點(diǎn)擊多個(gè)超鏈接,訪(fǎng)問(wèn)服務(wù)器多個(gè)web資源,然后關(guān)閉瀏覽器,這個(gè)過(guò)程稱(chēng)為一個(gè)會(huì)話(huà)。

  如果在打開(kāi)一個(gè)瀏覽器訪(fǎng)問(wèn)一個(gè)頁(yè)面后,再打開(kāi)一個(gè)瀏覽器訪(fǎng)問(wèn)同一個(gè)頁(yè)面,那這就是有兩個(gè)會(huì)話(huà);而打開(kāi)一個(gè)瀏覽器訪(fǎng)問(wèn)一個(gè)頁(yè)面后,通過(guò)這個(gè)頁(yè)面上的某個(gè)超鏈接是從新的瀏覽器打開(kāi)的,那依然只算一個(gè)會(huì)話(huà)。

  每個(gè)用戶(hù)在使用瀏覽器與服務(wù)器進(jìn)行會(huì)話(huà)的過(guò)程中,各自不可避免地會(huì)產(chǎn)生一些數(shù)據(jù),而程序要想辦法為每個(gè)用戶(hù)保存這些數(shù)據(jù)。比如,用戶(hù)點(diǎn)擊超鏈接通過(guò)一個(gè)產(chǎn)品Servlet購(gòu)買(mǎi)了一個(gè)商品,程序應(yīng)該想辦法保存這個(gè)商品,以便于用戶(hù)在點(diǎn)擊付款超鏈接時(shí)能再?gòu)母犊頢ervlet中看到這個(gè)商品并為其買(mǎi)單。

  使用Request對(duì)象是無(wú)法保存數(shù)據(jù)的,因?yàn)樵邳c(diǎn)擊商品和付款各自的Servlet是發(fā)送兩個(gè)不同的Request請(qǐng)求對(duì)象,而使用ServletContext對(duì)象則會(huì)發(fā)生多個(gè)用戶(hù)的線(xiàn)程安全問(wèn)題,使用轉(zhuǎn)發(fā)功能理論上可行,但是用戶(hù)體驗(yàn)將會(huì)大打折扣,每次點(diǎn)擊一個(gè)商品就會(huì)被要求付款。所以根據(jù)以上的需求,有兩種技術(shù)來(lái)保存會(huì)話(huà)過(guò)程中產(chǎn)生的數(shù)據(jù):一個(gè)是Cookie,一個(gè)是Session,Session技術(shù)將會(huì)在之后的篇章中介紹學(xué)習(xí)。

  本篇主要先講述Servlet中的Cookie技術(shù)。Cookie技術(shù)是客戶(hù)端技術(shù),程序把每個(gè)用戶(hù)的數(shù)據(jù)以cookie的形式寫(xiě)給用戶(hù)各自的瀏覽器。當(dāng)用戶(hù)使用瀏覽器再去訪(fǎng)問(wèn)服務(wù)器時(shí),就會(huì)帶著各自的數(shù)據(jù)過(guò)去,這樣web服務(wù)器處理的就是用戶(hù)各自的數(shù)據(jù)了。

下圖是一個(gè)會(huì)話(huà)過(guò)程中設(shè)置上一次訪(fǎng)問(wèn)時(shí)間的Cookie的簡(jiǎn)單過(guò)程:

  

創(chuàng)建一個(gè)Cookie對(duì)象就像平常創(chuàng)建一個(gè)Java對(duì)象一樣簡(jiǎn)單:

  

在使用構(gòu)造器時(shí)傳入Cookie的名和值這樣的鍵值對(duì)即可,我們?cè)诜?wù)器端要獲取從瀏覽器發(fā)來(lái)的Cookie數(shù)據(jù)可以使用請(qǐng)求對(duì)象的request.getCookies方法獲得一個(gè)Cookie數(shù)組,而我們想向?yàn)g覽器輸出Cookie時(shí)可以使用響應(yīng)對(duì)象的response.addCookie(Cookie)方法。

同時(shí)Cookie對(duì)象還有如下一些方法:

  

  getName方法用來(lái)獲取某個(gè)Cookie對(duì)象的名稱(chēng)。

  setValue方法和getValue方法分別用來(lái)設(shè)置和獲取某個(gè)Cookie對(duì)象的值。

  setMaxAge(int expires)方法是設(shè)置Cookie的有效期,如果沒(méi)有這句代碼,Cookie的有效期就是一個(gè)會(huì)話(huà)時(shí)間(即關(guān)閉瀏覽器該Cookie就不存在了),當(dāng)設(shè)置了Cookie的有效期后,Cookie會(huì)保存在瀏覽器指定的硬盤(pán)文件中,同時(shí)在這段時(shí)間內(nèi),每次訪(fǎng)問(wèn)服務(wù)器都會(huì)帶著Cookie過(guò)去。如果將該方法參數(shù)置為“0”,則服務(wù)器會(huì)指示瀏覽器刪除該Cookie。

  setPath方法是設(shè)置Cookie的有效路徑。表示在訪(fǎng)問(wèn)某些特定URL時(shí)才會(huì)帶Cookie過(guò)去。假設(shè)某個(gè)web應(yīng)用為【myservlet】,如果我們將setPath方法中的參數(shù)設(shè)置為“/myservlet”,那么訪(fǎng)問(wèn)該web應(yīng)用下所有的資源都會(huì)使瀏覽器發(fā)送Cookie過(guò)去;而如果我們將setPath方法中的參數(shù)設(shè)置為“/myservlet/pages”,那么只有訪(fǎng)問(wèn)該web應(yīng)用中的【pages】下的資源才會(huì)帶Cookie過(guò)去,而訪(fǎng)問(wèn)該web應(yīng)用中的其他資源則不會(huì)帶Cookie給服務(wù)器。如果我們沒(méi)有設(shè)置setPath方法,那么該Cookie的有效路徑默認(rèn)為創(chuàng)建Cookie對(duì)象的當(dāng)前程序所在目錄。注意,Cookie的路徑是給瀏覽器使用的(詳見(jiàn)《Servlet的學(xué)習(xí)之web路徑問(wèn)題》)

  setDomain方法是設(shè)置Cookie的有效域名,如: .sina.com(注意最前面有一個(gè)點(diǎn))。表示當(dāng)瀏覽器訪(fǎng)問(wèn)該域名時(shí)才會(huì)帶Cookie過(guò)去。但是現(xiàn)在瀏覽器基本全面阻止了這個(gè)可能作為不安全的功能,所以幾乎已經(jīng)被棄用。 

  舉例:我們?cè)L問(wèn)某個(gè)Servlet,而在訪(fǎng)問(wèn)這個(gè)Servlet時(shí)會(huì)將當(dāng)前訪(fǎng)問(wèn)時(shí)間作為Cookie中的值返回給客戶(hù)端,同時(shí)下次再次訪(fǎng)問(wèn)該Servlet時(shí),會(huì)顯示上一次客戶(hù)端來(lái)訪(fǎng)問(wèn)的時(shí)間:

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("您上次訪(fǎng)問(wèn)的時(shí)間是:");
  //獲取用戶(hù)上一次的訪(fǎng)問(wèn)時(shí)間并顯示
  Cookie[] cookies = request.getCookies();   //從請(qǐng)求中獲取客戶(hù)端發(fā)來(lái)的Cookie
  for(int i=0;cookies!=null && i<cookies.length;i++) {
   if(cookies[i].getName().equals("lastAccessTime")) { //獲取最后訪(fǎng)問(wèn)時(shí)間的Cookie
    Long mTime = Long.parseLong(cookies[i].getValue());  
    String lastAccessTime = new Date(mTime).toLocaleString();
    writer.write(lastAccessTime);
   }
  }
  //將本次登錄時(shí)間重新裝載進(jìn)Cookie中并返回給客戶(hù)端
  Cookie timeCookie = new Cookie("lastAccessTime", System.currentTimeMillis()+"");
  timeCookie.setMaxAge(1*24*60*60); //將Cookie有效期置為一天
  response.addCookie(timeCookie);  //將Cookie傳回客戶(hù)端
 }

第一次訪(fǎng)問(wèn)是沒(méi)有Cookie的,所以看不到訪(fǎng)問(wèn)時(shí)間:

  

但是我們通過(guò)HttpWatch觀(guān)察Response響應(yīng)包中的內(nèi)容已經(jīng)有了“Set-Cookie”響應(yīng)頭:

  

刷新后的第二次訪(fǎng)問(wèn)就可以看到了:

  

同時(shí)觀(guān)察HttpWatch中Request請(qǐng)求包的“Cookie”請(qǐng)求頭可以發(fā)現(xiàn):

  

  現(xiàn)在我們?cè)賮?lái)通過(guò)一個(gè)案例來(lái)學(xué)習(xí)Cookie,這是一個(gè)很常見(jiàn)的案例,比如我們?cè)谠L(fǎng)問(wèn)購(gòu)物網(wǎng)站的時(shí)候經(jīng)常會(huì)發(fā)現(xiàn)當(dāng)瀏覽了這個(gè)網(wǎng)站內(nèi)的某個(gè)商品的時(shí)候,下次繼續(xù)來(lái)訪(fǎng)問(wèn)這個(gè)網(wǎng)站,會(huì)有一個(gè)上次瀏覽物品的顯示。

  如果我們不是用登錄后將記錄保存在服務(wù)器端,而是使用Cookie技術(shù)來(lái)將記錄保存在客戶(hù)端的瀏覽器中(現(xiàn)實(shí)生活中當(dāng)然很少這樣使用,這里只是作為案例學(xué)習(xí)),那么我們應(yīng)該怎么做呢?

  首先我們必須在服務(wù)器要有兩個(gè)Servlet,一個(gè)在用戶(hù)眼中是用來(lái)顯示所有商品的,一個(gè)是用來(lái)顯示點(diǎn)擊某個(gè)商品之后詳細(xì)信息的。

 ?、牛脕?lái)顯示所有商品的Servlet需要完成如下功能:

   ①     在一個(gè)部分以超鏈接形式將數(shù)據(jù)庫(kù)中所有的商品顯示在該Servlet上。

  ?、?nbsp;    在另一個(gè)部分獲取用戶(hù)請(qǐng)求中的Cookie將之前瀏覽過(guò)的商品(通過(guò)Cookie中的商品id)顯示在該Servlet上。

 ?、?   用來(lái)顯示點(diǎn)擊某個(gè)商品之后詳細(xì)信息的Servlet需要完成如下功能:

   ①     在頁(yè)面上通過(guò)超鏈接的URL跟隨的參數(shù)(即商品id)來(lái)獲取該商品對(duì)象,同時(shí)將該商品對(duì)象的詳細(xì)信息輸出到Servlet頁(yè)面上。

  ?、?nbsp;    如果是用戶(hù)首次訪(fǎng)問(wèn),將用戶(hù)瀏覽商品的id作為Cookie直接返回,而如果是用戶(hù)再次訪(fǎng)問(wèn),則需要根據(jù)一定的條件來(lái)將這些Cookie的值進(jìn)行調(diào)整,以便易于顯示和滿(mǎn)足用戶(hù)體驗(yàn)。

   當(dāng)然,在這之前我們還需要做些準(zhǔn)備工作,我們需要建立商品對(duì)象,這里簡(jiǎn)單的以書(shū)為商品建立對(duì)象:

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;
 }
}

我們還需要一個(gè)數(shù)據(jù)庫(kù)來(lái)保存商品,這里我們先用一個(gè)類(lèi)來(lái)來(lái)保存(數(shù)據(jù)庫(kù)還沒(méi)學(xué)嘛T_T?。?,保存數(shù)據(jù)采用Map集合,這是因?yàn)槿绻袡z索會(huì)方便:

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核心技術(shù)》","fdaf"));
  map.put("3", new Product("3","《Java并發(fā)編程》","什么鬼"));
  map.put("4", new Product("4","《Head first 設(shè)計(jì)模式》","老王"));
  map.put("5", new Product("5","《HTML5權(quán)威手冊(cè)》","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();
  //從數(shù)據(jù)庫(kù)中取出要顯示在購(gòu)物網(wǎng)站首頁(yè)的商品
  Map<String,Product> map = ProductDatabase.getMap();
  if(map == null) {
   writer.print("您訪(fǎng)問(wèn)的寶貝已下架");
   return ;
  }
  for(Map.Entry<String, Product> en : map.entrySet()) {
   writer.print("<a href='/CookieProductProject/servlet/DetailGoodServlet?id="+en.getKey()+"' target='_blank' >"
              +en.getValue().getName()+" <br/>");
  }
  
  
  //顯示用戶(hù)之前瀏覽過(guò)的商品,要從用戶(hù)發(fā)送的請(qǐng)求中的Cookie里取得
  writer.print("<br/><br/>");
  writer.print("您最近瀏覽過(guò)的商品: <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/>");
    }
   }
  }
}

最后是點(diǎn)擊某個(gè)商品顯示詳細(xì)信息的Servlet:

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

  //通過(guò)用戶(hù)點(diǎn)擊商品的超鏈接而跟隨URL來(lái)的ID參數(shù)來(lái)獲取商品的詳細(xì)信息
  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());
  
  //同時(shí)通過(guò)Cookie將用戶(hù)觀(guān)看的商品以Cookie的形式回傳給用戶(hù)瀏覽器 
  Cookie[] allCookies = request.getCookies();
  
  Cookie cookie = creCookie(book.getId(),allCookies);
  cookie.setMaxAge(24*60*60);
  response.addCookie(cookie);

其中creCookie(String,Cookie[])是自定義方法,用于獲取用戶(hù)的cookie并添加本次瀏覽商品id再作為cookie返回:

private Cookie creCookie(String id, Cookie[] cookies) {
  Cookie cookie = null;
  
  if(cookies == null) { //如果cookies為空,說(shuō)明用戶(hù)首次訪(fǎng)問(wèn)
   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(); //此時(shí)獲取到的之前瀏覽過(guò)數(shù)據(jù)的歷史記錄,有多種情況
  String[] produIds = historyStr.split("\\_");
  
  //為了檢測(cè)數(shù)組中是否有包含當(dāng)前的id,建議使用集合,而且是使用鏈表結(jié)構(gòu)的集合
  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;
}

我們?cè)跒g覽器中進(jìn)行首次訪(fǎng)問(wèn):

  

隨便點(diǎn)擊個(gè)連接,可以看到該商品的詳細(xì)信息(其實(shí)瀏覽器也偷偷將該商品的id以cookie傳回了瀏覽器):

  

我們?cè)L問(wèn)商品顯示頁(yè)面再次【刷新】就可以看到剛才瀏覽過(guò)的商品了:

  

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • java二路歸并排序示例分享

    java二路歸并排序示例分享

    這篇文章主要介紹了java二路歸并排序示例,需要的朋友可以參考下
    2014-02-02
  • java微信公眾號(hào)開(kāi)發(fā)(搭建本地測(cè)試環(huán)境)

    java微信公眾號(hào)開(kāi)發(fā)(搭建本地測(cè)試環(huán)境)

    這篇文章主要介紹了java微信公眾號(hào)開(kāi)發(fā),主要內(nèi)容有測(cè)試公眾號(hào)與本地測(cè)試環(huán)境搭建,需要的朋友可以參考下
    2015-12-12
  • 如何處理器攔截器(HandlerInterceptor)

    如何處理器攔截器(HandlerInterceptor)

    這篇文章主要介紹了如何處理器攔截器(HandlerInterceptor)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • 一文帶你了解Spring中Bean名稱(chēng)加載機(jī)制

    一文帶你了解Spring中Bean名稱(chēng)加載機(jī)制

    這篇文章主要給大家介紹了Spring Framework如何從使用注解定義的Bean元數(shù)據(jù)中獲取到Bean的名稱(chēng),文中通過(guò)代碼示例給大家介紹的非常詳細(xì),具有一定的參考價(jià)值,需要的朋友可以參考下
    2024-01-01
  • Java之Springcloud Gateway內(nèi)置路由案例講解

    Java之Springcloud Gateway內(nèi)置路由案例講解

    這篇文章主要介紹了Java之Springcloud Gateway內(nèi)置路由案例講解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • Java內(nèi)部類(lèi)的繼承(全)

    Java內(nèi)部類(lèi)的繼承(全)

    這篇文章主要介紹了Java內(nèi)部類(lèi)的繼承,大家都知道JAVA內(nèi)部類(lèi)的構(gòu)造器必須連接指向其外圍類(lèi)對(duì)象的引用,所以在繼承內(nèi)部類(lèi)的時(shí)候,需要在導(dǎo)出類(lèi)的構(gòu)造器中手動(dòng)加入對(duì)基類(lèi)構(gòu)造器的調(diào)用,需要的朋友可以參考下
    2015-07-07
  • Spring事務(wù)處理Transactional,鎖同步和并發(fā)線(xiàn)程

    Spring事務(wù)處理Transactional,鎖同步和并發(fā)線(xiàn)程

    本文詳細(xì)講解了Spring事務(wù)處理Transactional,鎖同步和并發(fā)線(xiàn)程。對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-12-12
  • Mybatis Plus框架項(xiàng)目落地實(shí)踐分析總結(jié)

    Mybatis Plus框架項(xiàng)目落地實(shí)踐分析總結(jié)

    這篇文章主要為大家介紹了Mybatis Plus框架項(xiàng)目落地實(shí)踐分析總結(jié),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • Java import static及import原理區(qū)別解析

    Java import static及import原理區(qū)別解析

    這篇文章主要介紹了Java import static及import原理區(qū)別解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • sublime編譯器怎么運(yùn)行java程序

    sublime編譯器怎么運(yùn)行java程序

    Sublime是一款強(qiáng)大的代碼編輯器,它提供了豐富的功能和插件,可以幫助開(kāi)發(fā)者提高代碼的編寫(xiě)效率和質(zhì)量,通過(guò)安裝相關(guān)插件和進(jìn)行簡(jiǎn)單配置,我們可以輕松地在Sublime中編譯和運(yùn)行Java代碼,下面我們將詳細(xì)介紹如何配置Sublime,使其能夠高效地運(yùn)行Java代碼
    2024-06-06

最新評(píng)論