JavaWeb(九)HttpSession和登陸案例
阿新 • • 發佈:2019-02-10
HttpSession入門
1. HttpSession概述
- HttpSession是由JavaWeb提供的,用來會話跟蹤的類,儲存在伺服器端!
- HttpSession是Servlet三大域物件之一(request、session、application(ServletContext)),所以它也有
setAttribute()
,getAttribute()
,removeAttribute()
方法 - HttpSession底層依賴Cookie,或是URL重寫!
一個會話內只有一個session,比如說第一次訪問伺服器時,把session拿過來存點東西。當第二次訪問時,獲取的還是這個session(期間瀏覽器沒有關閉)。一個請求內一個request,一個會話內一個session
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,);
案例1
演示session會話的多次請求中共享資料
1. AServlet:向session域中儲存資料
2. BServlet:從session域中獲取資料
3. 演示:
> 第一個請求:訪問AServlet
public class AServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response){
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
//獲取session
HttpSession session = request.getSession();
//向session域中儲存資訊
session.setAttribute("wangyue","age5");
}
}
首先訪問這個Servlet
> 第二個請求:訪問BServlet
public class BServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response){
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response){
response.setContentType("text/html;charset=utf-8");
HttpSession session = request.getSession();
//get返回的是Object物件,所以向下轉型
String value = (String)session.getAttribute("wangyue");
response.getWriter().print("<h1 style='color:red' align='center'>" + value + "</h1>");
}
}
可以看到當訪問BServlet的時候:(只要瀏覽器不關閉,訪問時就一直有值)
案例2
儲存使用者登入資訊
- 案例相關頁面和Servlet:
> login.jsp:登入頁面
> succ1.jsp:只有登入成功費能訪問的頁面
> succ2.jsp:只有登入成功費能訪問的頁面
> LoginServlet:校驗使用者是否登入成功! - 各頁面和Servlet內容:
> login.jsp:提供登入表單,提交表單請求LoginServlet
> LoginServlet:獲取請求引數,校驗使用者是否登陸成功
<>失敗:儲存錯誤資訊到request域,轉發到login.jsp(這個頁面顯示request域中的錯誤資訊)
<>成功:儲存使用者資訊到session域中,重定向到succ1.jsp頁面,顯示session域中的使用者資訊
> succ1.jsp:從session域中獲取使用者資訊,如果不存在,顯示“您還沒有登入”。存在則顯示使用者資訊
> succ2.jsp:從session域中獲取使用者資訊,如果不存在,顯示“您還沒有登入”。存在則顯示使用者資訊
使用者只要沒有關閉瀏覽器,這個session就一直存在,那麼儲存在session中的使用者資訊也就一起存在!那麼使用者訪問succ1和succ2就會通過!
首先寫login.jsp:
%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登陸頁面</title>
</head>
<body>
<h1 style="color: orange" align="center">請提交登陸資訊</h1>
<%
/*
讀取Cookie,如果存在則顯示到使用者名稱中!
*/
String username = "";
Cookie[] cooks = request.getCookies();
for (Cookie cook: cooks
) {
if ("username".equals(cook.getName()))
username = cook.getValue();
}
%>
<%
String error = (String)request.getAttribute("error");
if (! (error==null)){
out.print("<b><font color='red'>" + error + "</font></b>");
}
%>
<form action="/my2/LoginServlet" method="post">
使用者名稱:<input type="text" name="username" value="<%=username%>"/><br/>
密碼:<input type="password" name="password"/><br/>
<input type="submit" value="提交">
</form>
</body>
</html>
然後是LoginServlet:
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response){
//處理中文問題
request.setCharacterEncoding("utf-8");
//獲取資訊
String username = request.getParameter("username");
String password = request.getParameter("password");
//校驗使用者名稱和密碼是否正確
if ("jjd".equalsIgnoreCase(username)) { //登陸失敗
request.setAttribute("error","使用者名稱或密碼錯誤");
RequestDispatcher rd1 = request.getRequestDispatcher("/login.jsp"); //得到轉發器,注意路徑上不加專案名!
rd1.forward(request,response); //轉發
}
else{ //登陸成功
Cookie cook = new Cookie("username",username); //建立一個Cookie儲存到本地,下次訪問時,直接將使用者名稱顯示
cook.setMaxAge(60*60*24); //設定儲存時間
response.addCookie(cook); //儲存Cookie
HttpSession session = request.getSession(); //獲取session物件
session.setAttribute("username",username); //向session域中儲存資訊
session.setAttribute("password",password);
response.sendRedirect("/my2/succ1.jsp"); //重定向到succ1.jsp
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response){
doPost(request,response);
}
}
然後是succ1.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>顯示資訊</title>
</head>
<body>
<h1 align="center">succ1</h1>
<%
String username = (String)session.getAttribute("username");
String password = (String)session.getAttribute("password");
%>
<%
if (username==null || password==null){
request.setAttribute("error","請登陸後檢視");
RequestDispatcher rd = request.getRequestDispatcher("/login.jsp");
rd.forward(request,response);
return;
}
%>
<p align="center">您的使用者名稱是:<%=username%></p>
<p align="center">您的密碼是:<%=password%></p><hr/>
<a href="/my2/succ2.jsp" target="_blank">點選這裡可以訪問succ2!</a>
</body>
</html>
然後是succ2.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登陸成功</title>
</head>
<body>
<%
String username = (String) session.getAttribute("username");
String password = (String) session.getAttribute("password");
%>
<%
if (username==null || password==null){
request.setAttribute("error","請登陸後檢視");
RequestDispatcher dr = request.getRequestDispatcher("/login.jsp");
dr.forward(request,response);
return;
}
%>
<h1 align="center">恭喜你!通關啦!</h1>
</body>
</html>
HttpSession原理
request.getSession()
方法:伺服器不會馬上建立session,只有在第一次獲取session時才會建立!即request.getSession()
!
- 獲取Cookie中sessionId:
<>如果jsessionId不存在,建立session,把session儲存起來,把新建立的sessionId儲存到Cookie中;
<>如果sessionId存在,通過sessionId查詢session物件,如果沒有查詢到,建立建立session,把session儲存起來,把新建立的sessionId儲存到Cookie中;
<>如果sessionId存在,通過sessionId查詢到了session物件,那麼就不會再建立session物件了;在伺服器端儲存的最大時間是30分鐘
<>返回session - 如果建立了新的session,瀏覽器會得到一個包含了sessionId的Cookie,這個Cookie的生命值是-1,只要不關閉瀏覽器,這個Cookie就會一直存在
- 下次請求時,再次執行
request.getSession()
方法時,因為可以通過Cookie中的sessionId找到session物件,所以與上次訪問時是同一個session物件。 request.getSession(false)
、request.getSession(true)
、request.getSession()
,後面兩個方法的效果相同
第一個方法:如果session快取中(如果Cookie不存在),不存在session,那麼返回null,並且不建立session
HttpSession的其他方法
String getId()
:獲取sessionId;int getMaxInactiveInterval()
:獲取session的最大不活動時間(秒),預設為30分鐘。當session在30分鐘內沒有使用,那麼Tomcat會在session池中移除這個sessionvoid invalidate()
:讓session失效!呼叫這個方法會讓session失效,當session失效後,客戶端再次請求,伺服器會為客戶端建立一個新的session並在響應中的Cookie新增這個sessionboolean isNew()
:檢視session是否為新。當客戶端第一次請求時,伺服器為客戶端建立session,但這時伺服器還沒有響應客戶端,也就是還沒有把sessionId傳送回來
JSESSIONID是由UUID產生的,Java的util包中提供了產生32位十六進位制數的方法:
public void fun{
//呼叫這個靜態方法就會產生UUID的例項
UUID uuid = UUID.randomUUID();
//這樣就產生了JSESSIONID
String str = uuid.toString();
//將其中的"-"去掉
String s = str.replace("-","").toUpperCase();
}
在web.xml中配置session的最大不活動時間
數字代表的是時間
<session-config>
<session-timeout>30</session-timeout>
</session-config>
URL重寫(理解)
就是把所有的頁面中的路徑,都使用response.encodeURL(String url)
處理一下。下面是這個方法的原理(把Cookie程式設計請求引數!)
- session依賴Cookie,目的是讓客戶端發出請求時歸還sessionId,這樣才能找到相應的session
- 如果客戶端禁用了Cookie,那麼就無法得到sessionId,那麼session就無用了!
- 也可以使用URL重寫來代替Cookie
>讓網站的所有超連結、表單中都新增一個特殊的請求引數,即sessionId
>這樣伺服器可以通過獲取請求引數得到sessionId,從而找到session物件。 response.encodeURL(String url)
這個方法會對url進行智慧的重寫:當請求中沒有歸還sessionId這個Cookie,那麼這個方法就會重寫url,當然這個url是指向本站的url
本人是菜鳥一枚,當做學習筆記寫部落格。謝謝各路大咖駐足審閱