首頁>技術>

一、簡介

http協議是無狀態的,在web會話中,為了記錄會話狀態資訊,將使用cookie和session,這裡基於原始碼進行介紹。

二、cookie

cookie是servlet發給客戶端瀏覽器的小量資訊,並由瀏覽器儲存,後續瀏覽器請求將會帶上前面儲存的資訊。cookie通常用於標識使用者身份。一個cookie有名稱、值和其它可選屬性(如備註、路徑、域名標識、最大存活時間、版本號等)。

2.1 cookie特點

1、瀏覽器通常對每個web服務支援20個cookie,並且瀏覽器總共支援300個cookie(換句話說,極端情況,瀏覽器最多支援15個web服務的cookie);

2、一個cookie通常限制4KB;

3、使用HttpServletResponse.addCookie方法新增cookie;

4、使用HttpServletRequest.getCookies方法獲取cookie;

5、不同路徑下cookie可以有相同名稱;

6、cookie返回瀏覽器時儲存在響應header中。

2.2 cookie原始碼

Cookie原始碼如下:

package javax.servlet.http;

import java.io.Serializable;

import java.text.MessageFormat;

import java.util.Locale;

import java.util.ResourceBundle;

public class Cookie implements Cloneable, Serializable {

//cookie名稱,其中$Name形式為保留字

private String name;

//cookie值

private String value;

//cookie備註

private String comment;

//域名,指定在哪個域名有效

private String domain;

//不設定表示同瀏覽器程序一樣的存活時間

private int maxAge = -1;

//路徑,表示cookie對指定路徑及子路徑有效,不設定表示瀏覽器訪問所路徑都帶上cookie,同時伺服器任何路徑回傳都不帶cookie資訊

private String path;

//是否使用SSL,是則只有在安全方式訪問傳送cookie,否則可以以非安全方式訪問傳送

private boolean secure;

//版本,等於1表示RFC2109++型別

private int version = 0;

//是否http只讀,即只能http或https訪問傳輸,如javascript等不能訪問

private boolean isHttpOnly = false;

//cookie構造器,填充名稱和值,其中名稱不能是保留字,忽略大小寫,

//保留字有Comment、Discard、Domain、Expires、Max-Age、Path、Secure、Version、以$開頭

public Cookie(String name, String value) {}

//各屬性值的get和set方法,略過

...

}

2.3 cookie示例

cookie讀取與新增示例如下:

package session;

import com.alibaba.fastjson.JSON;

import javax.servlet.ServletException;

import javax.servlet.http.Cookie;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

import java.util.Arrays;

import java.util.Objects;

public class CookieServlet extends HttpServlet {

@Override

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

resp.setContentType("application/json;charset=utf-8");

resp.getWriter().write("this is cookie");

Cookie idCookie = null;

String id = req.getParameter("id");

//獲取cookie

Cookie[] cookies = req.getCookies();

if (null != cookies && cookies.length > 0) {

idCookie = Arrays.stream(cookies).filter(t -> "c_id".equals(t.getName())).findFirst().orElse(null);

resp.getWriter().write(JSON.toJSONString(idCookie));

}

//新增cookie

idCookie = new Cookie("c_id", Objects.toString(id, "default"));

idCookie.setComment("cookie test");

idCookie.setDomain("dragon.com");

idCookie.setPath("/");

idCookie.setHttpOnly(true);

resp.addCookie(idCookie);

}

}

三、session

session與cookie相反,session是在服務端儲存狀態資訊,藉助cookie或重寫url的方式傳遞會話標識。在整個會話過程中,瀏覽器只需傳遞sessionId即可,服務端根據sessionId識別請求是哪個客戶端。

3.1 session特點

1、session會話資訊保存於服務端的記憶體中,使用HttpSession儲存;

2、客戶端第一次訪問服務端,需要會話時,才會建立session;

3、會話HttpSession物件有唯一sessionId,唯一標識客戶端,客戶端每次請求都要帶上;

4、session會話有儲存時間,單位是分鐘,預設為30,配置位於tomcat/conf/web.xml中的session-timout中;

5、使用HttpServletRequest.getSession(boolean create)獲取HttpSession,引數create為true時,沒有則新建session,另外過載方法HttpServletRequest.getSession()即是引數為true;

3.2 HttpSession原始碼

HttpSession原始碼如下:

package javax.servlet.http;

import java.util.Enumeration;

import javax.servlet.ServletContext;

public interface HttpSession {

//返回session的建立時間,單位是毫秒(自1970年1月1日GMT)

public long getCreationTime();

//返回session的唯一id

public String getId();

//返回session的最後訪問時間,單位是毫秒(自1970年1月1日GMT)

public long getLastAccessedTime();

//返回session所屬的ServletContext

public ServletContext getServletContext();

//設定session最長空閒時間,單位毫秒,超過則結束會話,值為0或負數則永不過期

public void setMaxInactiveInterval(int interval);

//獲取session最長空閒時間,單位毫秒

public int getMaxInactiveInterval();

//獲取指定名稱物件,沒有則返回null

public Object getAttribute(String name);

//獲取繫結物件名稱

public Enumeration<String> getAttributeNames();

//新增物件,若物件為null,則移出

//若物件實現HttpSessionBindingListener介面,則HttpSessionBindingListener.valueUnbound方法會被呼叫

//若指定名稱已經綁定了物件,則繫結物件被替換,如果繫結物件實現HttpSessionBindingListener介面,則繫結物件HttpSessionBindingListener.valueUnbound方法會被呼叫

public void setAttribute(String name, Object value);

//移出物件,若移出物件實現HttpSessionBindingListener介面,則移出物件HttpSessionBindingListener.valueUnbound方法會被呼叫

public void removeAttribute(String name);

//強制HttpSession失效,結束會話

public void invalidate();

//判斷當前session是否是新建的,true是,false否,

public boolean isNew();

}

3.3 session示例

會話中待存物件User.java:

import com.alibaba.fastjson.JSON;

import javax.servlet.http.HttpSessionBindingEvent;

import javax.servlet.http.HttpSessionBindingListener;

public class User implements HttpSessionBindingListener {

public String userId;

public User(String userId) {

this.userId = userId;

}

@Override

public void valueBound(HttpSessionBindingEvent event) {

Object obj = event.getValue();

System.out.println("bound,value:" + JSON.toJSONString(obj));

}

@Override

public void valueUnbound(HttpSessionBindingEvent event) {

Object obj = event.getSource();

System.out.println("unbound,new value:" + JSON.toJSONString(obj));

}

}

會話servlet:

import com.alibaba.fastjson.JSON;

import org.apache.commons.lang3.StringUtils;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;

import java.io.IOException;

public class SessionServlet extends HttpServlet {

@Override

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

resp.setContentType("application/json;charset=utf-8");

resp.getWriter().write("this is session");

String userId = req.getParameter("userId");

HttpSession session = req.getSession();

if(StringUtils.isNotBlank(userId)){

session.setAttribute("user", new User(userId));

}

resp.getWriter().write(JSON.toJSONString(session.getAttribute("user")));

}

16
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • servlet中RequestDispatcher解析及使用