javascript
Java-Web JSP、Cookie和Session域对象
一、JSP入門
? ? 1.什么是JSP
????????JSP(Java Server Pages)是JavaWeb服務器端的動態資源。它與html頁面的作用是相同的,顯示數據和獲取數據。
? ? 2.JSP的組成
????JSP = html + Java腳本(代碼片段) + JSP動態標簽
? ? 3.JSP語法
????? ? 3.1 JSP腳本
????????????? ? JSP腳本就是java代碼片段,分為三種:
????????(1)<%...%>:Java語句;
????????????????????????java代碼片段(常用),用于定義0~N條Java語句!方法內能寫什么,它就可以放什么!
????????(2)<%=…%>:Java表達式;
????????????? ? ? ??? ? java表達式,用于輸出一條表達式(或變量)的結果。response.getWriter().print( ... );這里能放什么,它就可以放什么!
????????(3)<%!...%>:Java定義類成員;
? ????????????????????? 聲明,用來創建類的成員變量和成員方法(基本不用)
????? ? 3.2 多個<%...%>可以通用
????????????????在一個JSP中多個<%...%>是相通的。例如:
????????????? ? 循環打印表格:
<body><h1>表格</h1><table border="1" width="50%"><tr><th>序號</th><th>用戶名</th><th>密碼</th></tr><%for(int i = 0; i < 10; i++) { %><tr><td><%=i+1 %></td><td>user<%=i %></td><td><%=100 + 1 %></td></tr><%}%></table></body>? ? 4.JSP原理
????????JSP是一種特殊的Servlet,當JSP頁面首次被訪問時,容器(Tomcat)會先把JSP編譯成Servlet,然后再去執行Servlet。所以JSP其實就是一個Servlet!
? ? 5.JSP注釋
? ??? ? 格式:<%-- ... --%>
????????JSP是需要先編譯成.java,再編譯成.class的。其中<%-- ... --%>中的內容在JSP編譯成.java時會被忽略的,即JSP注釋。
????????也可以在JSP頁面中使用html注釋:<!-- … -->,但這個注釋在JSP編譯成的.java中是存在的,它不會被忽略,而且會被發送到客戶端瀏覽器。但是在瀏覽器顯示服務器發送過來的html時,因為<!-- … -->是html的注釋,所以瀏覽器是不會顯示它的。
????6.JSP和Servlet的分工
????? * JSP:
????????????作為請求發起頁面,例如顯示表單、超鏈接。
????????????作為請求結束頁面,例如顯示數據。
????? * Servlet:
????????????作為請求中處理數據的環節。
????小案例演示:
????????客戶端請求該jsp頁面,輸出數字求和
<form method="post" action="/4.29/AServlet">請輸入數字:<input type="text" name="num1"/><br/>請輸入數字:<input type="text" name="num2"/><br/><input type="submit" value="求和" /></form>????? ? 該jsp將請求頁面發送到AServlet中,AServlet進行數據的處理,然后轉發到showSum.jsp中public class AServlet extends HttpServlet {public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//獲取請求的參數String num1 = request.getParameter("num1");String num2 = request.getParameter("num2");//把字符串轉成Integer類型Integer num11 = Integer.valueOf(num1);Integer num22 = Integer.valueOf(num2);int sum = num11 + num22;//把相加的結果保存到request域對象中request.setAttribute("sum", sum);//轉發到showSum.jsp中request.getRequestDispatcher("/sum/showSum.jsp").forward(request,response);}}????showSum頁面獲取到request傳遞過來的sum值,并輸出在客戶端中 <%Integer sum=(Integer)request.getAttribute("sum"); %><h3>和為<%=sum %></h3>
二、Cookie
? ? 1.Cookie概述
????????Cookie就是一個鍵和一個值構成的,隨著服務器端的響應發送給客戶端瀏覽器。然后客戶端瀏覽器會把Cookie保存起來,當下一次再訪問服務器時把Cookie再發送給服務器。
????????Cookie是由服務器創建,然后通過響應發送給客戶端的一個鍵值對。客戶端會保存Cookie,并會標注出Cookie的來源(哪個服務器的Cookie)。當客戶端向服務器發出請求時會把所有這個服務器Cookie包含在請求中發送給服務器,這樣服務器就可以識別客戶端了!
? ? 2.Cookie規范
????????????Cookie大小上限為4KB;
????????????一個服務器最多在客戶端瀏覽器上保存20個Cookie
????????????一個瀏覽器最多保存300個Cookie;
????????注意,不同瀏覽器之間是不共享Cookie的。也就是說在你使用IE訪問服務器時,服務器會把Cookie發給IE,然后由IE保存起來,當你在使用FireFox訪問服務器時,不可能把IE保存的Cookie發送給服務器。
? ? 3.Cookie與HTTP頭
????????Cookie是通過HTTP請求和響應頭在客戶端和服務器端傳遞的:
????????Cookie:請求頭,客戶端發送給服務器端;
????????????格式:Cookie: a=A; b=B; c=C。即多個Cookie用分號離開;
????????????????Set-Cookie:響應頭,服務器端發送給客戶端;
????????????????一個Cookie對象一個Set-Cookie:
????????????????????Set-Cookie: a=A
????????????????????Set-Cookie: b=B? ? 4.Cookie生命
????????可以通過setMaxAge(int)來設置Cookie的有效時間。
????????????cookie.setMaxAge(-1):cookie的maxAge屬性的默認值就是-1,表示只在瀏覽器內存中存活。一旦關閉瀏覽器窗口,那么cookie就會消失。
????????????cookie.setMaxAge(60*60):表示cookie對象可存活1小時。當生命大于0時,瀏覽器會把Cookie保存到硬盤上,就算關閉瀏覽器,就算重啟客戶端電腦,cookie也會存活1小時;
????????????cookie.setMaxAge(0):cookie生命等于0是一個特殊的值,它表示cookie被作廢!也就是說,如果原來瀏覽器已經保存了這個Cookie,那么可以通過Cookie的setMaxAge(0)來刪除這個Cookie。無論是在瀏覽器內存中,還是在客戶端硬盤上都會刪除這個Cookie。?
? ? 5.Cookie的path
????????現在有WEB應用A,向客戶端發送了10個Cookie,這就說明客戶端無論訪問應用A的哪個Servlet都會把這10個Cookie包含在請求中!但是也許只有AServlet需要讀取請求中的Cookie,而其他Servlet根本就不會獲取請求中的Cookie。這說明客戶端瀏覽器有時發送這些Cookie是多余的!
????????可以通過設置Cookie的path來指定瀏覽器,在訪問什么樣的路徑時,包含什么樣的Cookie。
????? ? (1)Cookie路徑與請求路徑的關系
????????當瀏覽器訪問服務器某個路徑時,需要歸還哪些Cookie給服務器呢?這由Cookie的path決定。
? ? ????瀏覽器訪問服務器的路徑,如果包含某個Cookie的路徑,那么就會歸還這個Cookie。
? ?????????例如:
? ? ? ????aCookie.path=/day11_1/; bCookie.path=/day11_1/jsps/; cCookie.path=/day11_1/jsps/cookie/;
? ? ? ????????<> 訪問:/day11_1/index.jsp時,歸還:aCookie
? ? ? ????????<> 訪問:/day11_1/jsps/a.jsp時,歸還:aCookie、bCookie
? ? ? ????????<> 訪問:/day11_1/jsps/cookie/b.jsp時,歸還:aCookie、bCookie、cCookie
? ? > Cookie的path默認值:當前訪問路徑的父路徑。例如在訪問/day11_1/jsps/a.jsp時,響應的cookie,那么這個cookie的默認path為/day11_1/jsps/
????????(2)設置Cookie路徑
????????設置Cookie的路徑需要使用setPath()方法,例如:
????????????????????cookie.setPath(“/cookietest/servlet”);
如果沒有設置Cookie的路徑,那么Cookie路徑的默認值當前訪問資源所在路徑,例如:
????訪問http://localhost:8080/cookietest/AServlet時添加的Cookie默認路徑為/cookietest;
????訪問http://localhost:8080/cookietest/servlet/BServlet時添加的Cookie默認路徑為/cookietest/servlet;
????訪問http://localhost:8080/cookietest/jsp/BServlet時添加的Cookie默認路徑為/cookietest/jsp;
? ? 6.Cookie中保存中文
????????Cookie的name和value都不能使用中文,如果希望在Cookie中使用中文,那么需要先對中文進行URL編碼,然后把編碼后的字符串放到Cookie中。
????向客戶端響應中添加Cookie
public class BServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response) {String name;try {name = URLEncoder.encode("姓名", "UTF-8");String value = URLEncoder.encode("張三", "UTF-8");Cookie c = new Cookie(name, value);c.setMaxAge(3600);response.addCookie(c);} catch (UnsupportedEncodingException e) {// TODO Auto-generated catch blocke.printStackTrace();}} }????從客戶端請求中獲取Cookie
public class CServlet extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {response.setContentType("text/html;charset=utf-8");Cookie[] cs = request.getCookies();if (cs != null) {for (Cookie cookie : cs) {String name = URLDecoder.decode(cookie.getName(), "UTF-8");String value = URLDecoder.decode(cookie.getValue(), "UTF-8");String s = name + ":" + value + "<br/>";response.getWriter().print(s);}}} }三、HttpSession
? ? 1.HttpSession概述
????? * HttpSession是由JavaWeb提供的,用來會話跟蹤的類。session是服務器端對象,保存在服務器端!!!
?? ? * HttpSession是Servlet三大域對象之一(request、session、application(ServletContext))。
????? * HttpSession底層依賴Cookie,或是URL重寫!
? ? 2.HttpSession的作用
? ????* 會話范圍:會話范圍是某個用戶從首次訪問服務器開始,到該用戶關閉瀏覽器結束!
? ??????會話:一個用戶對服務器的多次連貫性請求!所謂連貫性請求,就是該用戶多次請求中間沒有關閉瀏覽器!
????? * 服務器會為每個客戶端創建一個session對象,session就好比客戶在服務器端的賬戶,它們被服務器保存到一個Map中,這個Map被稱之為session緩存!
? ????????? Servlet中得到session對象:HttpSession session = request.getSession();
? ????????? Jsp中得到session對象:session是jsp內置對象之下,不用創建就可以直接使用!
????? * session域相關方法:
? ? ?????????void setAttribute(String name, Object value);
? ? ?????????Object getAttribute(String name);
? ? ?????????void removeAttribute(String name);
? ? 3.登陸案例
需要的頁面:
????login.jsp:登錄頁面,提供登錄表單;
????succ1.jsp:主頁,顯示當前用戶名稱,如果沒有登錄,退回到login頁面;
????LoginServlet:在login.jsp頁面提交表單時,請求本Servlet。在本Servlet中獲取用戶名、密碼進行校驗,如果用戶名、密碼錯誤,顯示“用戶名或密碼錯誤”,如果正確保存用戶名session中,然后重定向到succ1.jsp;
login.jsp
<!--獲取登陸過后給用戶名設置的Cookie值,下次方便登陸--><%String uname="";Cookie[] cookie=request.getCookies();if(cookie!=null){for(Cookie coo:cookie){if("username".equals(coo.getName())){uname=coo.getValue();}}}%> <!--獲取loginServlet發送過來的數據并顯示在瀏覽器上 --><h3>登陸界面</h3><br /> <% String message="";String judge=(String)request.getAttribute("judge");if(judge!=null){message=judge;}%><font color="red"><b><%=message%></b></font><form action="/4.29/loginServlet" method="post"><%-- 把cookie中的用戶名顯示到用戶名文本框中 --%>用戶名:<input type="text" name="username" value="<%=uname%>" /><br /> 密 碼:<input type="password" name="password" /><br /> <input type="submit" value="登陸" /></form>loginServlet
public class loginServlet extends HttpServlet {public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {request.setCharacterEncoding("UTF-8");// 獲取表單提交的參數String username = request.getParameter("username");String password = request.getParameter("password");// 對帳號進行校驗,成功的話if (!username.equals("hello")) {// 將帳號作為Cookie保存在瀏覽器中Cookie cookie = new Cookie("username", username);cookie.setMaxAge(60 * 60);response.addCookie(cookie);// 將獲取的參數存在session域中,方便succ1獲取HttpSession session = request.getSession();session.setAttribute("username", username);session.setAttribute("password", password);// 重定向到登陸成功頁面response.sendRedirect("/4.29/Login/succ1.jsp");// 失敗的話} else {// 保存錯誤信息到request域中request.setAttribute("judge", "用戶名或密碼錯誤。請重新輸入。");// 轉發到login.jsprequest.getRequestDispatcher("/Login/login.jsp").forward(request,response);}} }succ1.jsp
<%String username = (String) session.getAttribute("username");//獲取用戶名/*如果用戶名為null,向request域中保存錯誤信息,轉發到login.jsp*/if (username == null) {request.setAttribute("judge", "您還沒有登陸");request.getRequestDispatcher("/Login/login.jsp").forward(request, response);return;}%><h2>歡迎回來,<%=username%></h2>? ? 4.HttpSession原理
? * request.getSession()方法:
? ? > 獲取Cookie中的JSESSIONID:
? ? ? <> 如果sessionId不存在,創建session,把session保存起來,把新創建的sessionId保存到Cookie中
? ? ? <> 如果sessionId存在,通過sessionId查找session對象,如果沒有查找到,創建session,把session保存起來,把新創建的sessionId保存到Cookie中
? ? ? <> 如果sessionId存在,通過sessionId查找到了session對象,那么就不會再創建session對象了。
? ? ? <> 返回session
? ? > 如果創建了新的session,瀏覽器會得到一個包含了sessionId的Cookie,這個Cookie的生命為-1,即只在瀏覽器內存中存在,如果不關閉瀏覽器,那么Cookie就一直存在。
? ? > 下次請求時,再次執行request.getSession()方法時,因為可以通過Cookie中的sessionId找到session對象,所以與上一次請求使用的是同一session對象。??
? * 服務器不會馬上給你創建session,在第一次獲取session時,才會創建!request.getSession();
? * request.getSession(false)、request.getSession(true)、request.getSession(),后兩個方法效果相同
? ? > 第一個方法:如果session緩存中(如果cookie不存在),不存在session,那么返回null,而不會創建session對象。
? ? 5.Session與瀏覽器
????????session保存在服務器,而sessionId通過Cookie發送給客戶端,但這個Cookie的生命不-1,即只在瀏覽器內存中存在,也就是說如果用戶關閉了瀏覽器,那么這個Cookie就丟失了。
????????當用戶再次打開瀏覽器訪問服務器時,就不會有sessionId發送給服務器,那么服務器會認為你沒有session,所以服務器會創建一個session,并在響應中把sessionId中到Cookie中發送給客戶端。
????????你可能會說,那原來的session對象會怎樣?當一個session長時間沒人使用的話,服務器會把session刪除了!這個時長在Tomcat中配置是30分鐘,可以在${CATALANA}/conf/web.xml找到這個配置,當然你也可以在自己的web.xml中覆蓋這個配置!從客戶端請求中獲取Cookie。
<session-config><session-timeout>10</session-timeout></session-config>????????如果你打開網站的一個頁面開始長時間不動,超出了10分鐘后,再去點擊鏈接或提交表單時你會發現,你的session已經丟失了!
? ? 6.Session其他常用API
????????String getId():獲取sessionId;
????????int getMaxInactiveInterval():獲取session可以的最大不活動時間(秒),默認為30分鐘。當session在30分鐘內沒有使用,那么Tomcat會在session池中移除這個session;
????????void setMaxInactiveInterval(int interval):設置session允許的最大不活動時間(秒),如果設置為1秒,那么只要session在1秒內不被使用,那么session就會被移除;
????????long getCreationTime():返回session的創建時間,返回值為當前時間的毫秒值;
????????long getLastAccessedTime():返回session的最后活動時間,返回值為當前時間的毫秒值;
????????void invalidate():讓session失效!調用這個方法會被session失效,當session失效后,客戶端再次請求,服務器會給客戶端創建一個新的session,并在響應中給客戶端新session的sessionId;
????????boolean isNew():查看session是否為新。當客戶端第一次請求時,服務器為客戶端創建session,但這時服務器還沒有響應客戶端,也就是還沒有把sessionId響應給客戶端時,這時session的狀態為新。
? ? 7.URL重寫
????????我們知道session依賴Cookie,那么session為什么依賴Cookie呢?因為服務器需要在每次請求中獲取sessionId,然后找到客戶端的session對象。那么如果客戶端瀏覽器關閉了Cookie呢?那么session是不是就會不存在了呢?
????????其實還有一種方法讓服務器收到的每個請求中都帶有sessioinId,那就是URL重寫!在每個頁面中的每個鏈接和表單中都添加名為jSessionId的參數,值為當前sessionid。當用戶點擊鏈接或提交表單時也服務器可以通過獲取jSessionId這個參數來得到客戶端的sessionId,找到sessoin對象。
<body> <h1>URL重寫</h1> <a href='/day06_5/index.jsp;jsessionid=<%=session.getId() %>' <form action='/day06_5/index.jsp;jsessionid=<%=session.getId() %>' method="post"><input type="submit" value="提交"/> </form> </body>????????也可以使用response.encodeURL()對每個請求的URL處理,這個方法會自動追加jsessionid參數,與上面我們手動添加是一樣的效果。
<a href='<%=response.encodeURL("/day06_5/index.jsp") %>' >主頁</a> <form action='<%=response.encodeURL("/day06_5/index.jsp") %>' method="post"><input type="submit" value="提交"/> </form>????????使用response.encodeURL()更加“智能”,它會判斷客戶端瀏覽器是否禁用了Cookie,如果禁用了,那么這個方法在URL后面追加jsessionid,否則不會追加。????????
總結
以上是生活随笔為你收集整理的Java-Web JSP、Cookie和Session域对象的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java-Web 编码和路径
- 下一篇: gradle idea java ssm