javaweb入門筆記(5)-cookie和session

javaweb入門筆記(5)-cookie和session

標籤: javawebjavascript


[TOC]html


Cookie是客戶端技術;Session是服務器端技術。java

API:git

cookie

一些細節:github

  • 一個cookie只能標識一種信息,至少含有標識該信息的名稱和值
  • 瀏覽器通常只容許存放300個cookie,每一個站點最多存放20個,每一個cookie大小限制爲4KB
  • 默認是會話級別cookie(存儲於瀏覽器內存),瀏覽器進程關閉則刪除。有效期經過maxAge設置,存於硬盤,0表示刪除
  • 刪除cookie時,path必須一致,不然不會刪除

session

session對象由服務器建立,一個瀏覽器(會話)獨佔一個session對象web

session對象由服務器建立生命週期apache

  • 建立:調用request對象的getSession方法後纔會建立session對象;getSession(false)只獲取, 不建立
  • 銷燬:默認30分鐘沒人使用則自動銷燬。失效時間可在web.xml<session-config>標籤中使用<session-timeout>,單位分鐘;也可調用session對象的invalidate方法銷燬

實現原理

session基於cookie實現,將JSESSIONID寫回瀏覽器,這個cookie(JSESSIONID)默認沒設置有效期,關瀏覽器即銷燬。能夠自行回寫JSESSIONID覆蓋原cookie值api

示例代碼片斷:瀏覽器

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    HttpSession session = req.getSession();
    String sessionid = session.getId();
    Cookie cookie = new Cookie("JSESSIONID",sessionid);
    cookie.setPath("/s1");
    cookie.setMaxAge(30*60);
    resp.addCookie(cookie);
}

應用案例

  • 用戶登陸
  • 防止表單重複提交
  • 一次性驗證碼的校驗

小Tipstomcat

  • 通常大型網站不用session,使用cookie,減少服務器壓力
  • 若瀏覽器禁用cookie,需使用url自帶sessionid,相關方法:encodeURLencodeRedirectURL
  • 禁止表單重複提交:在javascript或者服務器實現。javascript防不死,用戶可經過修改js、自建表單提交,刷新頁面,後退等方法重複提交;服務器實現是給每一個表單一個隨機表單號
  • 生成表單號使用「令牌發生器」,爲保證惟一性(減少重複機率),使用單例。
  • base64編碼,三字節變四字節,每6位變8位(一字節),高位補零,每字節最大值爲63,故得名。
  • md5,經常使用於保存密碼(可能爲防止破解會加隨機數),校驗數據完整性

防止表單重複提交之令牌例子:

package org.iot.data;

import sun.misc.BASE64Encoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;

/**
 * Created by brian on 2016/1/27.
 */
public class TokenProcessor {//令牌
    /**
     * 1.構造方法私有
     * 2.本身建立一個
     * 3.對外暴露一個方法,容許獲取上面建立的對象
     */

    private TokenProcessor(){}

    private  static final TokenProcessor instance = new TokenProcessor();

    public static TokenProcessor getInstance(){
        return instance;
    }

    public String genetateToken(){
        String token = System.currentTimeMillis()+new Random().nextInt()+"";

        try {
            MessageDigest md =  MessageDigest.getInstance("md5");
            byte [] md5 =  md.digest(token.getBytes());
            //base64編碼
            BASE64Encoder encoder = new BASE64Encoder();
            return encoder.encode(md5);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
}

三個域對象

  • Session
  • Request
  • ServletContext

容器選用經驗:

  • 數據顯示完了就沒用了,則選用Request
  • 數據除了顯示外,稍後還會用,則選用Session
  • 數據除了顯示外,不只稍後會用,還會給別人用,則選用ServletContext

做者@brianway更多文章:我的網站 | CSDN | oschina

相關文章
相關標籤/搜索