Java全面細(xì)致講解Cookie與Session及kaptcha驗(yàn)證碼的使用
Cookie
1. 概念
是服務(wù)器通知客戶端保存鍵值對的一種技術(shù)。
cookie 是 servlet(服務(wù)器) 發(fā)送到 Web 瀏覽器(客戶端)的少量信息,這些信息由瀏覽器保存,然后發(fā)送回服務(wù)器。
客戶端有了 cookie 后,每次請求都發(fā)送給服務(wù)器
每個(gè) cookie 的大小不能超過 4 KB。
2. 創(chuàng)建Cookie
protected void createCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("utf-8"); resp.setContentType("text/html;charset=utf-8"); //1. 創(chuàng)建Cookie對象 Cookie cookie = new Cookie("key1", "value1"); //2. 通知客戶端保存 resp.addCookie(cookie); resp.getWriter().write("Cookie創(chuàng)建成功"); }
3. 服務(wù)器獲取Cookie
protected void getCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("utf-8"); resp.setContentType("text/html;charset=utf-8"); Cookie[] cookies = req.getCookies(); for (Cookie cookie : cookies) { //System.out.println(cookie); resp.getWriter().write("Cookie["+ cookie.getName() + " = " + cookie.getValue() + "] <br/>"); } // 查找特定的Cookie (項(xiàng)目中會把這個(gè)寫成工具類) Cookie need = null; for (Cookie cookie : cookies) { if ("key2".equals(cookie.getName())) { need = cookie; break; } } if (need != null) { // 不等于null,說明賦過值 resp.getWriter().write("找到了需要的Cookie"); } }
CookieUtils.java
// 查找特定的Cookie public static Cookie findCookie(Cookie[] cookies, String name) { if (cookies == null || name == null || cookies.length == 0) { return null; } for (Cookie cookie : cookies) { if (name.equals(cookie.getName())) { return cookie; } } return null; }
4. Cookie的修改
protected void updateCookie(HttpServletRequest req, HttpServletResponse resp) { // 第一種 // 修改需要先創(chuàng)建同key的Cookie對象,新值直接構(gòu)造傳入就行 Cookie newCookie1 = new Cookie("key1", "newValue1"); resp.addCookie(newCookie1); // 保存修改 // 第二種 Cookie newCookie2 = CookieUtils.findCookie(req.getCookies(), "key2"); if (newCookie2 != null) { newCookie2.setValue("newValue2"); // !注意不支持中文和一些符號,需要的話可以使用BASE64編碼 resp.addCookie(newCookie2); } }
5. Cookie的生命控制
Cookie的生命控制,即Cookie什么時(shí)候銷毀
API:setMaxAge(int expiry)
- 正值表示 cookie 將在經(jīng)過該值表示的秒數(shù)后過期 (關(guān)閉瀏覽器再次訪問還在)
- 負(fù)值意味著 cookie 不會被持久存儲,將在 Web 瀏覽器退出時(shí)刪除 (默認(rèn)是負(fù)數(shù),-1)
- 0 值表示馬上刪除 cookie。
修改后記得 resp.addCookie(cookie);
6. Cookie的有效路徑Path
有效路徑Path 可以過濾哪些Cookie可以發(fā)送給服務(wù)器,那些不發(fā)。
Path是通過請求的地址來進(jìn)行有效的過濾
例如:
cookie1 path=/工程路徑
cookie2 path=/工程路徑/abc
請求地址: (默認(rèn)是當(dāng)前的工程路徑)
http://ip:port/工程路徑/a.html
則cookie1會發(fā)送給服務(wù)器,cookie2不發(fā)送
http://ip:port/工程路徑/abc/d.html
cookie2,cookie1都發(fā)送!!
Cookie cookie = new Cookie("path1", "path1"); cookie.setPath(req.getContextPath() + "/abc"); // -> /工程路徑/abc
7. Cookie應(yīng)用-免用戶名密碼登錄
前端:login.jsp
<form action="/dynamicobject/loginServlet" method="post"> 用戶名: <input type="text" name="username" value="${cookie.username.value}"> <br/> 密碼: <input type="password" name="password" value="${cookie.password.value}"> <br/> <input type="submit" value="登錄"> </form>
后端:LoginServlet.java
public class LoginServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) { String username = req.getParameter("username"); String password = req.getParameter("password"); // 這里可以去數(shù)據(jù)庫查找,我們這里寫死了 if ("sutong".equals(username) && "123456".equals(password)) { Cookie c1 = new Cookie("username", username); c1.setMaxAge(60 * 60 * 24 * 7); // 一周內(nèi)有效 resp.addCookie(c1); Cookie c2 = new Cookie("password", password); // 一般密碼都會加密的 c2.setMaxAge(60 * 60 * 24 * 7); resp.addCookie(c2); System.out.println("登陸成功!"); } else { System.out.println("登陸失?。?); } } }
Session
1. 概念
Session是一個(gè)接口(HttpSession),就是會話。
用來維護(hù)一個(gè)客戶端和服務(wù)器之間關(guān)聯(lián)的一種技術(shù)。
每個(gè)客戶端都有它自己的一個(gè)Session。
Session會話中,我們經(jīng)常用來保存用戶登錄之后的信息。
2. 創(chuàng)建和獲取Session
創(chuàng)建和獲取都是一個(gè)函數(shù) request.getSession()
第一次調(diào)用是創(chuàng)建Session,之后調(diào)用都是獲取前面創(chuàng)建好的Sesson會話對象
isNew()
: 判斷是不是剛創(chuàng)建出來的(是不是新的)
getId()
: 每個(gè)會話都會有個(gè)唯一id值
protected void createOrGetSession(HttpServletRequest req, HttpServletResponse resp) throws IOException { req.setCharacterEncoding("utf-8"); resp.setContentType("text/html;charset=utf-8"); HttpSession session = req.getSession(); // 創(chuàng)建或獲取Session boolean flag = session.isNew(); // 判斷是否剛創(chuàng)建 String id = session.getId(); // id resp.getWriter().write("得到的Session的Id是" + id + "<br/>"); resp.getWriter().write("這個(gè)Session是否剛創(chuàng)建" + flag); }
3. Session域數(shù)據(jù)的存取
存?。?/p>
HttpSession session = req.getSession(); session.setAttribute("key1", "value1");
獲?。?/p>
String att = (String) req.getSession().getAttribute("key1"); // 返回的是Object
4. Session的生命周期的控制
API:public void setMaxInactiveInterval(int interval)
設(shè)置Session的超時(shí)時(shí)間(秒為單位),超過時(shí)長就會被銷毀(是最大不活躍間隔?。?/p>
正數(shù)是超時(shí)時(shí)長,負(fù)數(shù)是永不超時(shí)。注意:0不是立即銷毀,立即銷毀是session.invalidate()
獲取方法:public int getMaxInactiveInterval()
默認(rèn)是1800秒,即半小時(shí)。
因?yàn)樵赥omcat的服務(wù)器的配置文件web.xml中,有寫<session-timeout>30</session-timeout>
如果我希望我們工程的Session不想是30分鐘,可以在自己項(xiàng)目下的web.xml做以上相同的配置,就可以修改工程下所有Session的默認(rèn)超時(shí)時(shí)長了。
<session-config> <session-timeout>20</session-timeout> <!-- 分鐘為單位--> </session-config>
如果只想修改個(gè)別Session的超時(shí)時(shí)長,則需要使用session.setMaxInactiveInterval(interval)
方法
超時(shí)時(shí)長:指的是客戶端兩次請求的最大間隔時(shí)長?。?/p>
5. 瀏覽器和Session的關(guān)聯(lián)
當(dāng)客戶端沒有Cookie信息的時(shí)候,發(fā)送請求,服務(wù)器會(調(diào)用req.getSession())創(chuàng)建Session對象,每次創(chuàng)建Session會話的時(shí)候,都會創(chuàng)建一個(gè)Cookie對象,這個(gè)Cookie對象的key永遠(yuǎn)是:JSESSIONID,value是新創(chuàng)建出來的Session的Id。然后通過響應(yīng)頭返回給客戶端。
當(dāng)客戶端有了這個(gè)Cookie之后,每次請求會把Session的Id以Cookie的形式發(fā)送給服務(wù)器,然后服務(wù)器這邊會通過Id查找自己之前創(chuàng)建好的Session對象(調(diào)用req.getSession()),并返回。
如果上次創(chuàng)建的Session的沒過期的時(shí)候,我們手動把Cookie信息刪掉的話,服務(wù)器就沒法通過得到id,就沒法找到之前的那個(gè)Session對象,客戶端發(fā)送請求的時(shí)候,服務(wù)器則會重新創(chuàng)建新的Session會話,重復(fù)上面的操作。
Session 技術(shù),底層其實(shí)是基于 Cookie 技術(shù)來實(shí)現(xiàn)的
kaptcha驗(yàn)證碼
驗(yàn)證碼可以解決表單重復(fù)提交的情況
1. 使用
我們可以使用第三方的jar包,谷歌驗(yàn)證碼,kaptcha-2.3.2.jar
- 導(dǎo)包
- 在 web.xml 中去配置用于生成驗(yàn)證碼的Servlet程序 (即com.google.code.kaptcha.servlet.KaptchaServlet這個(gè)類,谷歌寫的)
<servlet> <servlet-name>KaptchaServlet</servlet-name> <servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>KaptchaServlet</servlet-name> <!-- 注意這里改的訪問名(看起來像個(gè)圖片),這樣的話訪問這個(gè)就是自動生成驗(yàn)證碼和圖片,并保存到Session域--> <url-pattern>/kaptcha.jpg</url-pattern> </servlet-mapping>
在表單中使用 img標(biāo)簽去顯示驗(yàn)證碼并使用它
<form action="" method="post"> 用戶名:<input type="text" name="username"> <br/> 密碼:<input type="password" name="password"> <br/> 驗(yàn)證碼:<input type="text" name="code"> <br/> <img id="code_img" src="http://localhost:8080/book/kaptcha.jpg" alt="圖片找不到"> <br/> <input type="button" value="注冊"> </form>
在服務(wù)器獲取谷歌生成的驗(yàn)證碼和客戶端發(fā)來的驗(yàn)證碼比較使用 (獲取后記得馬上刪除)
獲取谷歌生成的驗(yàn)證碼 :req.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
獲取用戶提交的驗(yàn)證碼:req.getSession().getAttribute("code")
2. 驗(yàn)證碼的切換
// 給驗(yàn)證碼圖片綁定單機(jī)事件 $("#code_img").click(function () { // 但這樣每次發(fā)一樣的請求,可能會被瀏覽器的緩存導(dǎo)致驗(yàn)證碼無法改變, // 緩存是根據(jù)工程名后面的資源名和參數(shù)產(chǎn)生的,所以我們可以在后面加上一個(gè)隨機(jī)的參數(shù)跳過緩存 //this.src = "http://localhost:8080/book/kaptcha.jpg"; this.src = "http://localhost:8080/book/kaptcha.jpg?d=" + new Date(); // 可以加個(gè)時(shí)間戳 });
到此這篇關(guān)于Java全面細(xì)致講解Cookie與Session及kaptcha驗(yàn)證碼的使用的文章就介紹到這了,更多相關(guān)Java Cookie Session kaptcha內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java web監(jiān)聽器統(tǒng)計(jì)在線用戶及人數(shù)
本文主要介紹了java web監(jiān)聽器統(tǒng)計(jì)在線用戶及人數(shù)的方法解析。具有很好的參考價(jià)值。下面跟著小編一起來看下吧2017-04-04java Bean與json對象間的轉(zhuǎn)換實(shí)例講解
在本篇文章里小編給大家整理的是關(guān)于java Bean與json間的轉(zhuǎn)換的實(shí)例內(nèi)容,有需要的朋友們吧可以學(xué)習(xí)參考下。2020-01-01SpringBoot實(shí)戰(zhàn):Spring如何找到對應(yīng)轉(zhuǎn)換器優(yōu)雅使用枚舉參數(shù)
這篇文章主要介紹了SpringBoot實(shí)戰(zhàn)中Spring是如何找到對應(yīng)轉(zhuǎn)換器優(yōu)雅的使用枚舉參數(shù),文中附有詳細(xì)的實(shí)例代碼有需要的朋友可以參考下,希望可以有所幫助2021-08-08lazy?init控制加載在Spring中如何實(shí)現(xiàn)源碼分析
這篇文章主要為大家介紹了lazy?init控制加載在Spring中如何實(shí)現(xiàn)源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09SpringBoot預(yù)防XSS攻擊的實(shí)現(xiàn)
XSS攻擊是一種在web應(yīng)用中的計(jì)算機(jī)安全漏洞,它允許惡意web用戶將代碼植入到提供給其它用戶使用的頁面,本文主要介紹了SpringBoot預(yù)防XSS攻擊的實(shí)現(xiàn),感興趣的可以了解一下2023-08-08深入解析Spring Bean初始化時(shí)和銷毀時(shí)的擴(kuò)展點(diǎn)
在Bean進(jìn)行初始化或者銷毀的時(shí)候,如果我們需要做一些操作,比如加載和銷毀一些資源或者執(zhí)行一些方法時(shí),那么就可以使用Spring提供的一些擴(kuò)展,今天主要分享初始化Bean時(shí)的三種方式和銷毀Bean時(shí)的三種方式,需要的朋友可以參考下2023-08-08Spring Cloud Alibaba Nacos Config加載配置詳解流
這篇文章主要介紹了Spring Cloud Alibaba Nacos Config配置中心實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-07-07