目錄

回顧
一.優(yōu)化表白墻代碼
二.Cookie 和 Session
1.Servlet中操作Cookie和Session Api
2.案例1:寫一個模擬登錄的案例:
3. 案例2:上傳文件
1.Servlet API
2.HttpServlet
DoXXX處理哪種Http方法會調(diào)用到對應的方法
init/destroy/service--->servlet的生命周期
3.HttpServletRequest ? Http請求 ? ? ?get系列方法
協(xié)議名(版本號)
url
query string
header
query String/body
HttpServletResponse Http響應 ? ?set系列方法
狀態(tài)碼
各種header
body
當前表白墻寫了多個DataSourse,使用單例模式優(yōu)化
餓漢:類加載創(chuàng)建實例
懶漢:效率更高(首次調(diào)用創(chuàng)建實例)
public class DBUtil {
? ? private static DataSource dataSource=null;
? ? public DataSource getDataSource(){
? ? ? ? //首次調(diào)用的時候創(chuàng)建實例
? ? ? ? if(dataSource==null){
? ? ? ? ? ? dataSource=new MysqlDataSource();
? ? ? ? ? ? ((MysqlDataSource)dataSource).setURL("jdbc:/mysql://127.0.0.1:3306/java105?characterEncoding=utf8&useSSL=false");
? ? ? ? ? ? ((MysqlDataSource)dataSource).setUser("root");
? ? ? ? ? ? //數(shù)據(jù)庫的密碼
? ? ? ? ? ? ((MysqlDataSource)dataSource).setPassword("1309411303");
? ? ? ? }
? ? ? ? return dataSource;
? ? }
}還要注意線程安全問題:
多個線程同時判定dataSouce為null,會創(chuàng)建多個實例
Servlet代碼中,涉及到多線程/線程安全問題,
Servlet寫的是一個服務(wù)器,同一時刻,可能要處理多個客戶端的請求,一旦有多個客戶端發(fā)送多個請求,服務(wù)器務(wù)必需要同時處理多個請求
Tomcat內(nèi)部正式使用了多線程的方式
解決方案:
1.加上volatile
private static ?volatile DataSource dataSource=null;2.加鎖
3.構(gòu)造方法私有
Cookie 是瀏覽器在本地持久化保存數(shù)據(jù)的一種方案
一個典型的使用方式,存儲登錄信息
在Servlet中也專門提供了相關(guān)的Api,讓我們來操作Cookie和Session
| 方法 | 描述 |
| HttpSession getSession() | 使用模式有倆中 參數(shù)填寫 false 判定當前會話是否存在,如果不存在,直接返回對應的HttpSession對象 參數(shù)填寫true,判定當前會話是否存在,如果不存在,就創(chuàng)建一個新的鍵值對,保存到哈希表中,并把生成的sessionId 返回到瀏覽器這里, 都是根據(jù)請求中的Cookie里的sessionId來查哈希表,如果存在則直接返回HttpSeeion對象 |
| Cookie[]getCookie() | 返回一個數(shù)組, 包含客戶端發(fā)送該請求的所有的 Cookie 對象. 會自動把Cookie 中的格式解析成鍵值對 |
| 方法 | 描述 |
| void addCookie(Cookie cookie) | 返回響應,你想給瀏覽器返回哪些cookie,都可以通過這個方法來添加 在這里添加的鍵值對,都會體現(xiàn)在Http響應報文的SetCookie字段上 |
| 方法 | 描述 |
| Object getAttribute(String name) | 該方法返回在該 session 會話中具有指定名稱的對象,如果沒 有指定名稱的對象,則返回 null |
| void setAttribute(String name, Object value) | 該方法使用指定的名稱綁定一個對象到該 session 會話 |
| boolean isNew() | 判定當前是否是新創(chuàng)建出的會話 |
| 方法 | 描述 |
| String getName() | 該方法返回 cookie 的名稱。名稱在創(chuàng)建后不能改變。(這個值是 Set Cooke 字段設(shè)置給瀏覽器的) |
| String getValue() | 該方法獲取與 cookie 關(guān)聯(lián)的值 |
| void setValue(String newValue) | 該方法設(shè)置與 cookie 關(guān)聯(lián)的值。 |
一個 HttpSession 對象里面包含多個鍵值對. 我們可以往 HttpSession 中存任何我們需要的信息.
每個 Cookie 對象就是一個鍵值對
理解會話機制
服務(wù)器同一時刻收到的請求是很多的. 服務(wù)器需要清除的區(qū)分清楚每個請求是從屬于哪個用戶, 就需要在服務(wù)器這邊記錄每個用戶令牌以及用戶的信息的對應關(guān)系
構(gòu)思內(nèi)容:
1.登錄頁面,用戶可以填寫用戶名+密碼
2.Servlet來處理登錄請求
3.使用另一個Servlet來生成主頁內(nèi)容(登錄成功后,跳轉(zhuǎn)到的頁面)
具體步驟
1.構(gòu)造form表單發(fā)給Servlet處理(注意三點匹配關(guān)系)
name(getParameter),method ,action

2.Servlet進行判定
當用戶點擊提交的時候,就會把剛才input框的name的值作為key,把input框里用戶的輸入,作為value,把這個鍵值對,放到body中提交給服務(wù)器,name屬性決定了鍵值對中的建,通過服務(wù)器getParameter獲取值

這里將字符串寫到前面,肯定不是空的,一定不會出現(xiàn)空指針異常(好處double check),雖然equls內(nèi)部已經(jīng)針對參數(shù)為null進行從處理了
3.登錄成功創(chuàng)建新的會話(SessionId),設(shè)置鍵值對,并重定向到指定的頁面
if("zhangsan".equals(username)&&"123".equals(password)){
//登陸成功
//a)創(chuàng)建一個會話,用戶剛登錄成功,之前是沒有會話的,重新分配一個新的會話給用戶
//創(chuàng)建sessionId和一個HttpSession 對象
//把這倆個內(nèi)容以鍵值對的形式插入到內(nèi)存的哈希表中
//把sessionId通過 set-cookie 寫到響應中
HttpSession session=req.getSession(true);
//隨意的設(shè)置鍵值對了(HttpSession 對象也相當于一個哈希表)
session.setAttribute("username","zhangsan");
//讓響應重定向到主頁
resp.sendRedirect("index");
}4.登錄失敗
//登錄失敗
resp.setStatus(403);
resp.setContentType("text/html;charset=utf8");
resp.getWriter().write("登錄失敗,用戶名或密碼錯誤");5.重定向后生成的主頁內(nèi)容
//登錄成功后,跳轉(zhuǎn)到的主頁
@WebServlet("/index")
public class IndexServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//首頁中先獲取session,此處的session正是剛才登錄頁的時候,登錄成功的邏輯中創(chuàng)建出來的
//此處參數(shù)寫作false即可,表示不新建,如果不存在,就返回null即可
HttpSession session=req.getSession(false);
if(session==null){
resp.setStatus(403);
resp.setContentType("text/html;charset=utf8");
resp.getWriter().write("你尚未登陸,不能訪問主頁");
return;
}
String username=(String) session.getAttribute("username");
resp.setContentType("text/html;charset=utf8");
resp.getWriter().write("歡迎來到主頁!" +username);
}
}理解3,5步驟

完整代碼:處理登錄請求+登錄頁面+跳轉(zhuǎn)后的服務(wù)器響應
package login;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
//使用這個類來處理登錄請求
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.從請求中獲取到頁面提交的用戶名和密碼
String username=req.getParameter("username");
String password=req.getParameter("password");
//2.驗證用戶名密碼是否正確
//正常這個操作是要查數(shù)據(jù)庫,此處為了簡單,直接寫成硬編碼了(把正確的用戶名和密碼寫死了)
//假定正確的密碼是 zhangsan 123
if("zhangsan".equals(username)&&"123".equals(password)){
//登陸成功
//a)創(chuàng)建一個會話,用戶剛登錄成功,之前是沒有會話的,重新分配一個新的會話給用戶
//創(chuàng)建sessionId和一個HttpSession 對象
//把這倆個內(nèi)容以鍵值對的形式插入到內(nèi)存的哈希表中
//把sessionId通過 set-cookie 寫到響應中
HttpSession session=req.getSession(true);
//隨意的設(shè)置鍵值對了(HttpSession 對象也相當于一個哈希表)
session.setAttribute("username","zhangsan");
//讓響應重定向到主頁
resp.sendRedirect("index");
}else{
//登錄失敗
resp.setStatus(403);
resp.setContentType("text/html;charset=utf8");
resp.getWriter().write("登錄失敗,用戶名或密碼錯誤");
}
}
}package login;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
//登錄成功后,跳轉(zhuǎn)到的主頁
@WebServlet("/index")
public class IndexServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//首頁中先獲取session,此處的session正是剛才登錄頁的時候,登錄成功的邏輯中創(chuàng)建出來的
//此處參數(shù)寫作false即可,表示不新建,如果不存在,就返回null即可
HttpSession session=req.getSession(false);
if(session==null){
resp.setStatus(403);
resp.setContentType("text/html;charset=utf8");
resp.getWriter().write("你尚未登陸,不能訪問主頁");
return;
}
String username=(String) session.getAttribute("username");
resp.setContentType("text/html;charset=utf8");
resp.getWriter().write("歡迎來到主頁!" +username);
}
}3. 案例2:上傳文件前端,搭配form表單,允許通過瀏覽器選中一個文件,上傳給服務(wù)器
| 方法 | 描述 |
| Part getPart(String name) | 獲取請求中給定 name 的文件 |
| Collection | 獲取所有的文件 |
| String getSubmittedFileName() | 獲取提交的文件名 |
| String getContentType() | 獲取提交的文件類型 |
| long getSize() | 獲取文件的大小 |
| void write(String path) | 把提交的文件數(shù)據(jù)寫入磁盤文件 |
| 方法 | 描述 |
| String getSubmittedFileName() | 獲取提交的文件名 |
| String getContentType() | 獲取提交的文件類型 |
| long getSize() | 獲取文件的大小 |
| void write(String path) | 把提交的文件數(shù)據(jù)寫入磁盤文件 |
注意對應關(guān)系

完整代碼
@WebServlet("/upload")
@MultipartConfig
public class UploadServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Part part=req.getPart("myfile");
System.out.println(part.getSubmittedFileName());
System.out.println(part.getSize());
System.out.println(part.getContentType());
part.write("c/program/result.jpg");
}
}你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧
本文名稱:Cookie和Session-創(chuàng)新互聯(lián)
路徑分享:http://www.chinadenli.net/article10/pcido.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁設(shè)計公司、響應式網(wǎng)站、ChatGPT、小程序開發(fā)、電子商務(wù)、網(wǎng)站設(shè)計
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)