JavaEEDay41 Servlet 與session
一、Servlet
注意事項:
1 . 防止線程安全問題
2 . 在使用同步代碼塊選擇鎖對象,通常會使用當前servlet程序對象
package a_thread;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 統計你是當前頁面的第幾個訪問者
* 利用一個計數器,每一次有一個人訪問就 + 1
*/
public class VisitedCount extends HttpServlet {
int count = 1;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
/*int count = 1;
局部變量,每一次調用doGet方法,都會重新創建一個count變量, 無法作爲計數器*/
//告訴瀏覽器解析數據的方式和使用的字符集
resp.setContentType("text/html;charset=utf-8");
//服務器發送數據使用的字符集
resp.setCharacterEncoding("utf-8");
synchronized (this) {
/*
這裏因爲操作了共享資源計數器count,爲了避免線程的安全問題,這裏採用加鎖的方式(同步代碼塊)
鎖對象用this,this表示當前Servlet程序類VisitedCount的對象,因爲在Tomcat服務器
上當VisitedCount對象被創建和init之後,不會在創建新的VisitedCount對象,滿足鎖對象
的基本要求
*/
resp.getWriter().write("你是第" + count + "訪問者");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
count++;
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
}
}
ServletConfig對象
在 web.xml 中補充以下信息:
<servlet>
<servlet-name>ConfigServlet</servlet-name>
<servlet-class>b_servletconfig.ConfigServlet</servlet-class>
<!-- servlet程序的初始化參數 -->
<init-param>
<param-name>user</param-name>
<param-value>root</param-value>
</init-param>
<init-param>
<param-name>password</param-name>
<param-value>123456</param-value>
</init-param>
</servlet>
在web.xml文件中利用標籤來定義servlet初始化參數,主要包含兩個子標籤
當Tomcat服務器程序啓動,WEB容器在創建servlet時,會把初始化參數封裝到ServletConfig對象中,這個ServletConfig對象,會作爲Servlet對象的初始化方法init的參數
【注意】
在一個Servlet 對應一個ServletConfig
package b_servletconfig;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ConfigServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//因爲獲取的是當前ConfigServlet程序的ServletConfig對象,因此使用this調用getServletConfig()方法
ServletConfig config = this.getServletConfig();
//獲取當前Servlet程序的名字
System.out.println(config.getServletName());
//根據param-name獲取對應的param-value值
String value = config.getInitParameter("user");
System.out.println(value);
//獲取到所有初始化參數的枚舉類型
Enumeration<String> names = config.getInitParameterNames();
while (names.hasMoreElements()) {
String name = names.nextElement();
System.out.println(name + ":" + config.getInitParameter(name));
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
}
}
用於獲取參數值以及屬性;
ServletContext
表示當前整個WEB應用,一個WEB應用有且只有一個ServletContext對象
1 獲取WEB應用的路徑
ServletContext context = this.getServletContext();
context.getContextPath();
request.getContextPath();
2.WEB應用的全局參數
3.ServletContext 是一個域對象
request,session 也是域對象
可以利用ServletContext域對象特徵,完成在整個WEB項目中的數據共享傳遞
不單單能傳遞基本數據類型,也可以傳遞類對象類型
setAttribute(String name, Object value);
Object getAttribute(String name);
4.轉發和重定向
轉發會攜帶數據,但是重定向沒有攜帶數據;
WEB服務器接受到客戶端的請求之後,讓Tomcat服務器去調用另一個WEB資源,這稱之爲轉發
-
request域轉發
-
request.setAttribute(String name, Object value);
-
轉發的方法
req.getRequestDispatcher(String uri).forward(HttpServletRequest req, HttpServletResponse resp);
- uri:服務器端要訪問別的WEB資源路徑,這裏是服務器端的地址,一般用 / 開頭,表示WEB項目的根目錄
- HttpServletRequest req: 原本用戶請求當前頁面的request對象
- HttpServletResponse resp: 原本用戶請求當前頁面生成對應的response對象
-
-
重定向
response.sendRedirect(String url);
這個URL是相對於webapps的,是提供給瀏覽器使用的URL
推薦寫法是:
response.sendRedirect(request.getContextPath() + “重定向地址”);
【注意】
在重定向的情況下,request域不能使用
會話控制
- 軟件程序中的會話 一次會話: 打開瀏覽器 -> 訪問服務器上的內容 -> 關閉瀏覽器
登錄業務場景: 打開瀏覽器 -> 訪問登錄頁面 -> 輸入 用戶名 密碼 驗證碼 -> 發送給服務器 -> 服務器驗證消息 -> 返回給瀏覽器 -> 瀏覽器加載主頁
發現:在百度首頁登錄了用戶名,在所有的百度服務的頁面下都是一個登錄的狀態
購物車場景: 在手機淘寶APP選擇了一個商品,加入購物車
打開瀏覽器 -> 淘寶網 -> 登錄賬號 -> 查看購物車,也可以看到手機APP添加商品
這裏的購物車數據在那裏保存???
會話控制技術: 管理 瀏覽器客戶端 和 服務器 之間進行會話過程生產的會話數據
會話控制技術
Cookie技術: 會話數據保存在瀏覽器客戶端,也就是用戶本地
Session技術:會話數據保存在服務器上
Cookie技術
-
核心方法:
1 . 創建Cookie對象
Cookie(String name, String value);
2 . 設置Cookie
setValue(String value) //通過name來設置Cookie的Value
setPath(String path); //設置Cookie的有效範圍
setMaxAge(int time); //設置最大有效時間
3 . 發送Cookie到瀏覽器保存
response.addCookie(Cookie c); //發送Cookie給瀏覽器
4 . 服務器接受瀏覽器訪問時帶來的Cookie數據
Cookie[] request.getCookies(); -
Cookie有一定的侷限性
1 . 限制數據類型 必須是String
2 . 不能保存中文
3 . Cookie保存數據容量較小,只有4KB
如果要保存4KB以上數據,或者要保存中文數據,就不能使用Cookie技術,只能用Session
【但是有一個前提】
如果瀏覽器沒有打開Cookie功能, Session也無法使用
Sesion的特點:
會話數據保存在 服務器 上,可以生成一個臨時或者永久的temp文件
Session技術
HttpSession
1 . 獲取Session對象
HttpSession getSession();
HttpSession getSession(boolean create); // 再創建一個 session
2 . 設置Session對象
void setMaxInactiveInterval(int interval); //設置Session 的有效時間
void invalidate(); //銷燬Session
String getId(); //獲取Session的ID
3 . Session也是一個域對象,這裏可以保存數據屬性到Session
void setAttribute(String name, Object value); //設置Session裏面保存是會話數據內容,可以保存一個對象
Object getAttribute(String name); //獲取到Session裏面數據
void removeAttribute(String name); //清空Session裏面的數據