您好,登錄后才能下訂單哦!
如何在servlet項(xiàng)目中使用cookie?相信很多沒有經(jīng)驗(yàn)的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個(gè)問題。
Cookie技術(shù)是客戶端技術(shù),程序把每個(gè)用戶的數(shù)據(jù)以cookie的形式寫給用戶各自的瀏覽器。當(dāng)用戶使用瀏覽器再去訪問服務(wù)器時(shí),就會(huì)帶著各自的數(shù)據(jù)過去,這樣web服務(wù)器處理的就是用戶各自的數(shù)據(jù)了。
下圖是一個(gè)會(huì)話過程中設(shè)置上一次訪問時(shí)間的Cookie的簡單過程:
創(chuàng)建一個(gè)Cookie對象就像平常創(chuàng)建一個(gè)Java對象一樣簡單:
在使用構(gòu)造器時(shí)傳入Cookie的名和值這樣的鍵值對即可,我們在服務(wù)器端要獲取從瀏覽器發(fā)來的Cookie數(shù)據(jù)可以使用請求對象的request.getCookies
方法獲得一個(gè)Cookie數(shù)組,而我們想向?yàn)g覽器輸出Cookie時(shí)可以使用響應(yīng)對象的response.addCookie(Cookie)
方法。
同時(shí)Cookie對象還有如下一些方法:
getName方法用來獲取某個(gè)Cookie對象的名稱。
setValue方法和getValue方法分別用來設(shè)置和獲取某個(gè)Cookie對象的值。
setMaxAge(int expires
)方法是設(shè)置Cookie的有效期,如果沒有這句代碼,Cookie的有效期就是一個(gè)會(huì)話時(shí)間(即關(guān)閉瀏覽器該Cookie就不存在了),當(dāng)設(shè)置了Cookie的有效期后,Cookie會(huì)保存在瀏覽器指定的硬盤文件中,同時(shí)在這段時(shí)間內(nèi),每次訪問服務(wù)器都會(huì)帶著Cookie過去。如果將該方法參數(shù)置為“0”,則服務(wù)器會(huì)指示瀏覽器刪除該Cookie。
setPath方法是設(shè)置Cookie的有效路徑。表示在訪問某些特定URL時(shí)才會(huì)帶Cookie過去。假設(shè)某個(gè)web應(yīng)用為【myservlet】,如果我們將setPath方法中的參數(shù)設(shè)置為“/myservlet”,那么訪問該web應(yīng)用下所有的資源都會(huì)使瀏覽器發(fā)送Cookie過去;而如果我們將setPath方法中的參數(shù)設(shè)置為“/myservlet/pages”,那么只有訪問該web應(yīng)用中的【pages】下的資源才會(huì)帶Cookie過去,而訪問該web應(yīng)用中的其他資源則不會(huì)帶Cookie給服務(wù)器。如果我們沒有設(shè)置setPath方法,那么該Cookie的有效路徑默認(rèn)為創(chuàng)建Cookie對象的當(dāng)前程序所在目錄。注意,Cookie的路徑是給瀏覽器使用的(詳見《Servlet的學(xué)習(xí)之web路徑問題》)
setDomain方法是設(shè)置Cookie的有效域名,如: .sina.com
(注意最前面有一個(gè)點(diǎn))。表示當(dāng)瀏覽器訪問該域名時(shí)才會(huì)帶Cookie過去。但是現(xiàn)在瀏覽器基本全面阻止了這個(gè)可能作為不安全的功能,所以幾乎已經(jīng)被棄用。
舉例:我們訪問某個(gè)Servlet,而在訪問這個(gè)Servlet時(shí)會(huì)將當(dāng)前訪問時(shí)間作為Cookie中的值返回給客戶端,同時(shí)下次再次訪問該Servlet時(shí),會(huì)顯示上一次客戶端來訪問的時(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("您上次訪問的時(shí)間是:"); //獲取用戶上一次的訪問時(shí)間并顯示 Cookie[] cookies = request.getCookies(); //從請求中獲取客戶端發(fā)來的Cookie for(int i=0;cookies!=null && i<cookies.length;i++) { if(cookies[i].getName().equals("lastAccessTime")) { //獲取最后訪問時(shí)間的Cookie Long mTime = Long.parseLong(cookies[i].getValue()); String lastAccessTime = new Date(mTime).toLocaleString(); writer.write(lastAccessTime); } } //將本次登錄時(shí)間重新裝載進(jìn)Cookie中并返回給客戶端 Cookie timeCookie = new Cookie("lastAccessTime", System.currentTimeMillis()+""); timeCookie.setMaxAge(1*24*60*60); //將Cookie有效期置為一天 response.addCookie(timeCookie); //將Cookie傳回客戶端 }
第一次訪問是沒有Cookie的,所以看不到訪問時(shí)間:
但是我們通過HttpWatch觀察Response響應(yīng)包中的內(nèi)容已經(jīng)有了“Set-Cookie”響應(yīng)頭:
刷新后的第二次訪問就可以看到了:
同時(shí)觀察HttpWatch中Request請求包的“Cookie”請求頭可以發(fā)現(xiàn):
現(xiàn)在我們再來通過一個(gè)案例來學(xué)習(xí)Cookie,這是一個(gè)很常見的案例,比如我們在訪問購物網(wǎng)站的時(shí)候經(jīng)常會(huì)發(fā)現(xiàn)當(dāng)瀏覽了這個(gè)網(wǎng)站內(nèi)的某個(gè)商品的時(shí)候,下次繼續(xù)來訪問這個(gè)網(wǎng)站,會(huì)有一個(gè)上次瀏覽物品的顯示。
如果我們不是用登錄后將記錄保存在服務(wù)器端,而是使用Cookie技術(shù)來將記錄保存在客戶端的瀏覽器中(現(xiàn)實(shí)生活中當(dāng)然很少這樣使用,這里只是作為案例學(xué)習(xí)),那么我們應(yīng)該怎么做呢?
首先我們必須在服務(wù)器要有兩個(gè)Servlet,一個(gè)在用戶眼中是用來顯示所有商品的,一個(gè)是用來顯示點(diǎn)擊某個(gè)商品之后詳細(xì)信息的。
⑴.用來顯示所有商品的Servlet需要完成如下功能:
?、?nbsp; 在一個(gè)部分以超鏈接形式將數(shù)據(jù)庫中所有的商品顯示在該Servlet上。
?、?nbsp; 在另一個(gè)部分獲取用戶請求中的Cookie將之前瀏覽過的商品(通過Cookie中的商品id)顯示在該Servlet上。
?、? 用來顯示點(diǎn)擊某個(gè)商品之后詳細(xì)信息的Servlet需要完成如下功能:
?、?nbsp; 在頁面上通過超鏈接的URL跟隨的參數(shù)(即商品id)來獲取該商品對象,同時(shí)將該商品對象的詳細(xì)信息輸出到Servlet頁面上。
?、?nbsp; 如果是用戶首次訪問,將用戶瀏覽商品的id作為Cookie直接返回,而如果是用戶再次訪問,則需要根據(jù)一定的條件來將這些Cookie的值進(jìn)行調(diào)整,以便易于顯示和滿足用戶體驗(yàn)。
當(dāng)然,在這之前我們還需要做些準(zhǔn)備工作,我們需要建立商品對象,這里簡單的以書為商品建立對象:
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ù)庫來保存商品,這里我們先用一個(gè)類來來保存(數(shù)據(jù)庫還沒學(xué)嘛T_T?。4鏀?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)威手冊》","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ù)庫中取出要顯示在購物網(wǎng)站首頁的商品 Map<String,Product> map = ProductDatabase.getMap(); if(map == null) { writer.print("您訪問的寶貝已下架"); 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/>"); } //顯示用戶之前瀏覽過的商品,要從用戶發(fā)送的請求中的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/>"); } } } }
最后是點(diǎn)擊某個(gè)商品顯示詳細(xì)信息的Servlet:
response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); PrintWriter writer = response.getWriter(); //通過用戶點(diǎn)擊商品的超鏈接而跟隨URL來的ID參數(shù)來獲取商品的詳細(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í)通過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(); //此時(shí)獲取到的之前瀏覽過數(shù)據(jù)的歷史記錄,有多種情況 String[] produIds = historyStr.split("\\_"); //為了檢測數(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; }
我們在瀏覽器中進(jìn)行首次訪問:
隨便點(diǎn)擊個(gè)連接,可以看到該商品的詳細(xì)信息(其實(shí)瀏覽器也偷偷將該商品的id以cookie傳回了瀏覽器):
我們訪問商品顯示頁面再次【刷新】就可以看到剛才瀏覽過的商品了:
看完上述內(nèi)容,你們掌握如何在servlet項(xiàng)目中使用cookie的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。