Java Web之會話技術


  客戶端與服務器通信過程中,會產生一些數據。比如,A和B分別登陸了某寶購物網站,A買了一個Android手機,B買了一個iPhone手機,當結賬時,web服務器需要分別對用戶A和B的信息分別保存。根據Java Web之Servlet技術中所說,HttpServletRequest對象和ServletContext對象都可以保存數據,但是這二者在該情形下是不適合使用的。

  • 客戶端的每次請求,服務器都會產生一個HttpServletRequest對象,該對象只保存本次請求所傳遞的數據。由於購買和結賬是兩個不同的請求,所以使用HttpServletRequest對象保存信息會造成丟失。
  • 同一個Web應用共享一個ServletContext對象,所以當多個用戶結賬時無法區分哪個商品是哪個用戶購買的,這顯然是不可行的。

1、Cookie對象

  Cookie是一種會話技術,它用於將會話過程中的數據保存在用戶的瀏覽器中,從而使瀏覽器和服務器更好的交互。服務器向客戶端發送Cookie時,會在HTTP響應頭字段增加Set-Cookie字段,該字段設置的Cookie遵循一定規則,比如以鍵值對形式保存,Cookie屬性值可以有多個,但是這些屬性之間必須以分號和空格分隔。以下是一個Cookie示例:

Set-Cookie:"lastTime="2016-05-21 12:03:10"; Version=1"

Cookie使用

  為了封裝Cookie信息,Servlet API中提供了一個javax.servlet.http.Cookie類,該類包含了生成Cookie信息和提取Cookie信息各個屬性的方法,Cookie唯一的構造方法下:

public Cookie(java.lang.String name, java.lang.String value)

  構造方法中,name用於指定Cookie名稱,value指定Cookie的值,注意,Cookie一旦創建后,其名稱就不允許更改了,Cookie值是可以更改的。Cookie類常用的方法如下:

方法 功能
String getName() 返回Cookie名稱
 void setValue(String newValue)/String getValue() 設置/獲取Cookie值
void setMaxAge(int expiry)/int getMaxAge() 設置/獲取Cookie在瀏覽中保存有效的秒數
void setPath(String uri)/public String getPath() 設置/獲取Cookie向有效目錄路徑
void setDomain(String pattern)/String getDomain() 設置/獲取Cookie的有效域
void setSecure(boolean flag)/boolean getSecure() 設置/獲取Cookie是否只能使用安全的協議傳送

 

Cookie示例

  利用Cookie技術實現提示上次訪問時間功能。

package zzz;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name="CookieTest", urlPatterns={"/CookieTest"})
public class CookieTest extends HttpServlet {
    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 指定響應編碼方式
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        
        String lastTime = null;
        Cookie[] cookies = request.getCookies();
        for (int i = 0; cookies != null && i < cookies.length; i++) {
            if (cookies[i].getName().equals("lastTime")) {
                lastTime = cookies[i].getValue();
            }
        }
        
        if (lastTime == null) {
            out.println("你好,這是你首次訪問網站");
        }
        else {
            out.println("你好,你上次訪問該網站時間為:" + lastTime);
        }
        
        // 創建cookie,將當前時間記錄到cookie中並返回
        String time = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
        Cookie cookie = new Cookie("lastTime", time);
        response.addCookie(cookie);
    }
    
    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
        this.doGet(request, response);
    }
}

 

2、Session技術

  Cookie技術可以將用戶信息保存在瀏覽器中,並且可在多次請求中共享數據,但是如果傳遞的信息比較多, 使用Cookie技術明顯加大服務端程序的處理難度。此時,可以使用Session技術來實現,其通過將會話數據保存在服務端。注意:Session對象對應着一個ID,所以一般是需要客戶端記錄該對象的ID,通常情況下,Session是通過Cookie技術來傳遞Session對象ID的。

 

  Session對象是與每個請求緊密相關的,HttpServletRequest定義了用於獲取Session對象的getSession()方法,如下所示:

public HttpSession getSession(boolean create);
public HttpSession getSession();

  第一個getSession()根據參數值決定是否創建新的Session對象,如果參數為true,則相關的HttpSession對象不存在時創建新的HttpSession對象,如果參數為false,則不會創建新的HttpSession對象。第二個getSession()方法則相當於第一個方法參數為true的情況。HttpSession常用方法如下:

方法 功能
String getId() 返回該HttpSession對象關聯的會話標識號
int getMaxInactiveInterval() 返回當前HttpSession對象最大生存周期,單位為s
void invalidate() 強制使HttpSession對象失效
void setAttribute(String name, Object value) 將一個對象與一個名稱關聯后存儲到HttpSession對象中
Object getAttribute(String name) 返回當前HttpSession對象中指定名稱的屬性對象
void removeAttribute(String name) 從當前HttpSession對象中刪除指定名稱屬性對象

   Web服務器管理HttpSession對象時,會采用超時管理機制判斷客戶單是否還在繼續訪問。一定時間內,某個客戶一直沒有訪問,Web服務器就會認為該客戶端已經結束請求,將與該客戶會話所關聯的HttpSession對象給垃圾回收掉。如果之后該客戶端再次訪問,則重新創建一個新的HttpSession對象。會話的有效時間可以再web.xml中設置,默認值有Servlet容器定義,在tomcat的安裝目錄中的web.xml中有如下配置,就是設置Session超時時間的,單位為分鍾。

<session-config>
    <session-timeout>30</session-timeout>
</session-config>

Session示例

  利用Session技術實現提示上次訪問時間功能。

package zzz;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@WebServlet(name="SessionTest", urlPatterns={"/SessionTest"})
public class SessionTest extends HttpServlet {
    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 指定響應編碼方式
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        
        String user = null;
        Cookie[] cookies = request.getCookies();
        for (int i = 0; cookies != null && i < cookies.length; i++) {
            if (cookies[i].getName().equals("user")) {
                user = cookies[i].getValue();
            }
        }
        
        HttpSession session = request.getSession();
        if (user == null) {
            out.println("你好,這是你首次訪問網站");
            Cookie cookie = new Cookie("user", "luoxn28");
            response.addCookie(cookie);
        }
        else {
            String time = (String) session.getAttribute("lastTime");
            out.println("你好,你上次訪問該網站時間為:" + time);
        }
        
        String lastTime = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
        session.setAttribute("lastTime", lastTime);
    }
    
    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
        this.doGet(request, response);
    }
}

 

參考資料

  1、Java Web之Servlet技術

  2、《Java Web程序開發入門》6章


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM