經(jīng)營閱讀網(wǎng)站需要怎么做排名優(yōu)化方法
目錄
HttpServlet
HttpServletRequest
?HttpServletResponse
錯誤頁面
設置網(wǎng)頁自動刷新時間
構造重定向相應
js發(fā)起http請求?
服務器端對js發(fā)起的http請求進行處理
前端獲取后端數(shù)據(jù),添加到當前頁面的末尾,代碼示例:?
?前后端交互:引入數(shù)據(jù)庫(存儲數(shù)據(jù))
1)引入數(shù)據(jù)庫依賴
?編輯
?編輯2)建庫建表
3)編寫數(shù)據(jù)庫代碼
整體代碼?
利用Cookie和Session實現(xiàn)登錄邏輯
1.登錄頁面(html)
2.通過一個Servlet處理上述的登錄請求
3.網(wǎng)站主頁,通過另一個servlet生成的動態(tài)頁面
掌握如下三個類,就可以完成Servlet的大部分開發(fā)了
- HttpServlet
- HttpServletRequest
- HttpServletResponse
URI:唯一資源標識符
URL:唯一資源定位/地址符
HttpServlet
HttpServlet繼承這個類,重寫里面的方法,目的就是為了把咱們子集定義的代碼,“插入到”tomcat中,HttpServlet的常用方法如下:
方法名稱 | 調(diào)用時機 |
init | 在 HttpServlet 實例化之后被調(diào)用一次,初始化 |
destory | 在 HttpServlet 實例不再使用的時候調(diào)用一次,釋放資源 |
service | 收到 HTTP 請求的時候調(diào)用 |
doGet | 收到 GET 請求的時候調(diào)用 ( 由 service 方法調(diào)用 ) |
doPost | 收到 POST 請求的時候調(diào)用 ( 由 service 方法調(diào)用 ) |
doPut/doDelete/doOptions/... | 收到其他請求的時候調(diào)用 ( 由 service 方法調(diào)用 ) |
- 直接干掉Tomcat進程,完全來不及調(diào)用destory的;
- 通過8005管理端口,給Tomcat發(fā)送一個“停機”指令,這個時候是能夠執(zhí)行destory的。
init / destory / service 這三個方法都不需要手動調(diào)用,會被tomcat在合適的時機,自動調(diào)用,咱們寫好代碼,讓別人來幫忙調(diào)用,這種方式就叫做 “框架”?,也就是一個程序的主體部分,都已經(jīng)被其他大佬們寫完了,有些細節(jié)內(nèi)容,允許咱們插入咱們自己寫的自定義的邏輯.
HttpServletRequest
方法 | 描述 |
String getProtocol() | 返回請求協(xié)議的名稱和版本。 |
String getMethod() | 返回請求的 HTTP 方法的名稱,例如, GET 、 POST 或 PUT 。 |
String getRequestURI() | 從協(xié)議名稱直到 HTTP 請求的第一行的查詢字符串中,返回該 請求的 URL 的一部分。 |
String getContextPath() | 返回指示請求上下文的請求 URI 部分。 |
String getQueryString() | 返回包含在路徑后的請求 URL 中的查詢字符串。 |
InputStream getInputStream() | 用于讀取請求的 body 內(nèi)容 . 返回一個 InputStream 對象 . |
Enumeration getParameterNames() | 返回一個 String 對象的枚舉,包含在該請求中包含的參數(shù)的名 稱。 |
String getParameter(String name) | 以字符串形式返回請求參數(shù)的值,或者如果參數(shù)不存在則返回 null 。 |
String[] getParameterValues(String name) | 返回一個字符串對象的數(shù)組,包含所有給定的請求參數(shù)的值, 如果參數(shù)不存在則返回 null 。 |
Enumeration getHeaderNames() | 返回一個枚舉,包含在該請求中包含的所有的頭名。 |
String getHeader(String name) | 以字符串形式返回指定的請求頭的值。 |
String getCharacterEncoding() | 返回請求主體中使用的字符編碼的名稱。 |
String getContentType() | 返回請求主體的 MIME 類型,如果不知道類型則返回 null 。 |
int getContentLength() | 以字節(jié)為單位返回請求主體的長度,并提供輸入流,或者如果 長度未知則返回 -1 。 |
上述的方法都是get系列方法(都是讀方法),沒有set系列(沒有寫方法),當前拿到的HttpServletRequest,這些數(shù)據(jù)的內(nèi)容已經(jīng)確定下來了,程序員是不應該修改的.
前端將數(shù)據(jù)交給后端
除了query string之外,還可以通過http請求的body來傳遞參數(shù)(POST)。
(1)直接通過form表單
????????(body的格式就是query string的格式)
????????Content-Type:application/x-www-form-urlencoded
(2)直接使用json
????????(body的格式就是json)
????????Content-Type:application/json
這三種方式本質上是等價的,都是把鍵值對數(shù)據(jù)交給服務器,前兩種方法servlet天然支持的,json這種方法需要引入第三方庫。
在java中,json的第三方庫是非常多的,這里我們使用jackson(jackson是spring官方推薦的庫,也被spring集成起來了)
步驟如下:
1)下載導入jackson到項目中,通過maven
Maven Repository: Search/Browse/Explore (mvnrepository.com)
(2)使用jackson
一個類兩個方法
ObjectMapper
- 把json字符串,映射成java的一個對象(read方法)
- 把一個java對象,映射成json字符串(write方法)
Request request = objectMapper.readValue(req.getInputStream(),Request.class);1.核心工作就是把json字符串,映射成java 對象,參數(shù)就是json字符串(json字符串是在http的body中的,就需要通過HttpServletRequest中的getInputStream來獲取到)
此處把這個流對象直接傳給readValue,readValue內(nèi)部就會讀取InputStream中的所有數(shù)據(jù)(http請求的body,也就是json字符串),進一步嘗試解析
2.按照json的格式,進行解析,把json字符串,解析成map(鍵值對)
3.把map轉換成對象,在方法的第二個參數(shù)
如下示例:
import com.fasterxml.jackson.databind.ObjectMapper;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 java.io.IOException;
import java.io.ObjectInputValidation;class Request()
{public String username;public String password;
}
class Response{public boolean ok;
}@WebServlet("/json")
public class JsonParameterServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {ObjectMapper objectMapper = new ObjectMapper();Request request = objectMapper.readValue(req.getInputStream(),Request.class);System.out.println("username="+request.username);System.out.println("password="+request.password);Response response=new Response();response.ok=true;//把響應對象轉成json字符串String respJson=objectMapper.writeValueAsString(response);resp.setContentType("application/json;charset=utf8");resp.getWriter().write(respJson);}
}
?HttpServletResponse
核心方法
方法 | 描述 |
void setStatus(int sc) | 為該響應設置狀態(tài)碼 |
void setHeader(String name, String value) | 設置一個帶有給定的名稱和值的 header. 如果 name 已經(jīng)存在 , 則覆蓋舊的值 |
void addHeader(String name, String value) | 添加一個帶有給定的名稱和值的 header. 如果 name 已經(jīng)存在 , 不覆蓋舊的值, 并列添加新的鍵值對 |
void setContentType(String type) | 設置被發(fā)送到客戶端的響應的內(nèi)容類型。 |
void setCharacterEncoding(String charset) | 設置被發(fā)送到客戶端的響應的字符編碼( MIME 字符集)例如,UTF-8 |
void sendRedirect(String location) | 使用指定的重定向位置 URL 發(fā)送臨時重定向響應到客戶端 |
PrintWriter getWriter() | 用于往 body 中寫入文本格式數(shù)據(jù) |
OutputStream getOutputStream() | 用于往 body 中寫入二進制格式數(shù)據(jù) |
錯誤頁面
resp.sendError(404,"這個頁面是一個錯誤頁面")
設置網(wǎng)頁自動刷新時間
resp.setHeader("refresh","1");
構造重定向相應
resp.setStatus(302); resp.setHeader("Location","https://www.baidu.com");
header需要有一個Location屬性,描述要跳轉到哪里?,除了這種寫法外,還有如下另一種方法:
resp.sendRedirect("https://www.baidu.com");
使用ajax,需要先引入JQeury第三方庫
jquery (v3.7.1) - jQuery 是一個高效、精簡并且功能豐富的 JavaScript 工具庫。它提供的 API 易于使用且兼容眾多瀏覽器,這讓諸如 HTML 文檔遍歷和操作、事件處理、動畫和 Ajax 操作更加簡單。 | BootCDN - Bootstrap 中文網(wǎng)開源項目免費 CDN 加速服務
https://www.bootcdn.cn/jquery/
鏈接如上,選擇如下鏈接
在script標簽引入jquery
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
js發(fā)起http請求?
// 把用戶填寫的內(nèi)容,發(fā)送給服務器,讓服務器來保存// $ 是jquery提供的全局變量,ajax是$的一個方法// ajax的參數(shù)是一個js對象,可以有很多屬性let body={"from":from,"to":to,"message":message}//上述body是一個js對象,還需要轉換成json字符串let jsonString = JSON.stringify(body)$.ajax({type:'post',url:'message',contentType:'application/json; charset=utf8',data:jsonString,//這里的body與上面的body不是同一個,是響應報文的正文success:function(body){// 這個回調(diào)就是收到響應之后要執(zhí)行的代碼了}});
此處success回調(diào)函數(shù),不是立即執(zhí)行的,而是在瀏覽器收到服務器返回的成功這樣的響應的時候,才會執(zhí)行function ,這個函數(shù)的第一個參數(shù),是響應數(shù)據(jù)的body中的內(nèi)容。
服務器端對js發(fā)起的http請求進行處理
import com.fasterxml.jackson.databind.ObjectMapper;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 java.io.IOException;
import java.util.ArrayList;class Message{
// 確保java代碼中類的屬性名字和json中的屬性名字保持一致,才能夠自動填充public String from;public String to;public String message;@Overridepublic String toString() {return "Message{" +"from='" + from + '\'' +", to='" + to + '\'' +", message='" + message + '\'' +'}';}
}
@WebServlet("/message")
public class MessageServlet extends HttpServlet {private ObjectMapper objectMapper = new ObjectMapper();private List<Message> messageList = new ArrayList<>();@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//使用jackson讀取前端發(fā)來的數(shù)據(jù),把這個數(shù)據(jù)保存到服務器這邊Message message = objectMapper.readValue(req.getInputStream(),Message.class);System.out.println("請求中收到的message:"+ message);//保存數(shù)據(jù)最簡單的是直接內(nèi)存中存儲,使用集合類//但是這樣做一旦重啟服務器,一切數(shù)據(jù)都沒有了,一般存儲到數(shù)據(jù)庫中messageList.add(message);//返回一個響應resp.setStatus(200);resp.getWriter().write("ok");}
}
這里啟動服務器后,不能直接訪問/message,需要訪問.html路徑
當瀏覽器要向服務器獲取資源,?服務器方使用List類型的數(shù)組存儲歷史數(shù)據(jù),轉成的json字符串就是一個json數(shù)組,jackson自動遍歷List里的每個元素,把每個元素分別轉成json字符串。
@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setStatus(200);resp.setContentType("application/json;charset=utf-8");String respJson = objectMapper.writeValueAsString(messageList);resp.getWriter().write(respJson);}
上述代碼setStatus和setContentType必須在getWriter前面,否則不會生效?
? ? $.ajax{
? ? ? ? type:'get',
? ? ? ? url:'message',
? ? ? ? success:function(body){
? ? ? ? ? ? //處理服務器返回的響應數(shù)據(jù)。(json格式的數(shù)組)
? ? ? ? }
? ? }
//當響應中,header帶有ContentType:"application/json",JQuery就會自動把json字符串解析成js對象了,如果沒有帶ContentType:"application/json"就需要通過js代碼JSON.parse方法手動把json字符串轉成js對象
前端獲取后端數(shù)據(jù),添加到當前頁面的末尾,代碼示例:?
$.ajax{type:'get',url:'message',success:function(body){//處理服務器返回的響應數(shù)據(jù)。(json格式的數(shù)組)//由于響應中已經(jīng)有ContentType:"application/json"了,就不需要使用parse方法手動轉換了//body = JSON.parse(body);//拿到 container這個元素let containerDiv = document.querySelector('.container');//處理服務器返回的響應數(shù)據(jù)。(json格式的數(shù)組了)for(let i=0;i<body.length;i++){//body是一個數(shù)組,此時的message也就是js對象了//這個message對象里有三個屬性:from、to、messagelet message = body[i];//根據(jù)message對象構建html片段,把這個片段給顯示到網(wǎng)頁上//createElement 方法就能構造一個html標簽//此時就得到了<div></div>let div = document.createElement('div');//還需要給這個div設置一個屬性div.className = 'row';//設置內(nèi)容div.innerHTML = message.from + " 對 " + message.to + " 說:" +message.message;//將這個div添加到containerDiv末尾containerDiv.appendChild(div);}}
?前后端交互:引入數(shù)據(jù)庫(存儲數(shù)據(jù))
1)引入數(shù)據(jù)庫依賴
Maven倉庫鏈接
Maven Repository: Search/Browse/Explore (mvnrepository.com)
搜索MySQL,選擇如下:
這里選擇5.1.47版本
復制如下代碼
復制到pom.xml里

2)建庫建表
create database if not exists message_wall charset utf8;
use message_wall;
-- 刪表的目的是為了防止之前數(shù)據(jù)庫里有一樣的表
drop table if exists message;
use message_wall;
create table message(`from` varchar(1024),`to` varchar(1024),message varchar(1024));
3)編寫數(shù)據(jù)庫代碼
// 1. 創(chuàng)建數(shù)據(jù)源
private DataSource dataSource = new MysqlDataSource();
((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3307/message_wall?characterEncoding=utf8&useSSL=false");
((MysqlDataSource) dataSource).setUser("root");
((MysqlDataSource) dataSource).setPassword("root");
// 2. 建立連接
Connection connection = dataSource.getConnection();// 3. 構造 SQL
String sql = "insert into message values(?, ?, ?)";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setString(1, message.from);
statement.setString(2, message.to);
statement.setString(3, message.message);// 3. 執(zhí)行 SQL
statement.executeUpdate();// 4. 回收資源
statement.close();
connection.close();
整體代碼?
MessageServlet.java
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;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.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;class Message {public String from;public String to;public String message;@Overridepublic String toString() {return "Message{" +"from='" + from + '\'' +", to='" + to + '\'' +", message='" + message + '\'' +'}';}
}@WebServlet("/message")
public class MessageServlet extends HttpServlet {private ObjectMapper objectMapper = new ObjectMapper();// 引入數(shù)據(jù)庫, 此時 messageList 就不再需要了.// private List<Message> messageList = new ArrayList<>();private DataSource dataSource = new MysqlDataSource();@Overridepublic void init() throws ServletException {// 1. 創(chuàng)建數(shù)據(jù)源((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3307/message_wall?characterEncoding=utf8&useSSL=false");((MysqlDataSource) dataSource).setUser("root");((MysqlDataSource) dataSource).setPassword("root");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 讀取前端發(fā)來的數(shù)據(jù), 把這個數(shù)據(jù)保存到服務器這邊.Message message = objectMapper.readValue(req.getInputStream(), Message.class);System.out.println("請求中收到的 message: " + message);// 最簡單的辦法, 直接在內(nèi)存中保存. 可以使用一個集合類, 把所有收到的 message 都存到內(nèi)存中.// 很明顯, 保存到內(nèi)存, 并非是一個非常合理的辦法. 后續(xù)一旦重啟服務器, 數(shù)據(jù)丟失了.// 相比之下, 把這個數(shù)據(jù)持久化存儲到數(shù)據(jù)庫中, 更科學的.// messageList.add(message);// 插入數(shù)據(jù)庫try {save(message);} catch (SQLException e) {throw new RuntimeException(e);}// 返回一個響應resp.setStatus(200);resp.getWriter().write("ok");// resp.setContentType("application/json");// resp.getWriter().write("{ ok: true }");}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 通過這個方法來處理當前獲取消息列表的 get 請求. 不需要解析參數(shù), 直接返回數(shù)據(jù)即可.resp.setStatus(200);resp.setContentType("application/json; charset=utf8");// 從數(shù)據(jù)庫查詢List<Message> messageList = null;try {messageList = load();} catch (SQLException e) {throw new RuntimeException(e);}String respJson = objectMapper.writeValueAsString(messageList);resp.getWriter().write(respJson);}private void save(Message message) throws SQLException {// 通過這個方法把 message 插入到數(shù)據(jù)庫中// 1. 建立連接Connection connection = dataSource.getConnection();// 2. 構造 SQLString sql = "insert into message values(?, ?, ?)";PreparedStatement statement = connection.prepareStatement(sql);statement.setString(1, message.from);statement.setString(2, message.to);statement.setString(3, message.message);// 3. 執(zhí)行 SQLstatement.executeUpdate();// 4. 回收資源statement.close();connection.close();}private List<Message> load() throws SQLException {// 通過這個方法從數(shù)據(jù)庫讀取到 message.// 1. 建立連接Connection connection = dataSource.getConnection();// 2. 構造 SQLString sql = "select * from message";PreparedStatement statement = connection.prepareStatement(sql);// 3. 執(zhí)行 sqlResultSet resultSet = statement.executeQuery();// 4. 遍歷結果集合List<Message> messageList = new ArrayList<>();while (resultSet.next()) {Message message = new Message();message.from = resultSet.getString("from");message.to = resultSet.getString("to");message.message = resultSet.getString("message");messageList.add(message);}// 5. 回收資源resultSet.close();statement.close();connection.close();// 6. 返回 messageListreturn messageList;}
}
?message_wall.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>表白墻</title><style>/* * 通配符選擇器, 是選中頁面所有元素 */* {/* 消除瀏覽器的默認樣式. */margin: 0;padding: 0;box-sizing: border-box;}.container {width: 600px;margin: 20px auto;}h1 {text-align: center;}p {text-align: center;color: #666;margin: 20px 0;}.row {/* 開啟彈性布局 */display: flex;height: 40px;/* 水平方向居中 */justify-content: center;/* 垂直方向居中 */align-items: center;}.row span {width: 80px;}.row input {width: 200px;height: 30px;}.row button {width: 280px;height: 30px;color: white;background-color: orange;/* 去掉邊框 */border: none;border-radius: 5px;}/* 點擊的時候有個反饋 */.row button:active {background-color: grey;}</style><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
</head>
<body>
<div class="container"><h1>表白墻</h1><p>輸入內(nèi)容后點擊提交, 信息會顯示到下方表格中</p><div class="row"><span>誰: </span><input type="text"></div><div class="row"><span>對誰: </span><input type="text"></div><div class="row"><span>說: </span><input type="text"></div><div class="row"><button id="submit">提交</button></div><!-- <div class="row">xxx 對 xx 說 xxxx</div> -->
</div><script>// 實現(xiàn)提交操作. 點擊提交按鈕, 就能夠把用戶輸入的內(nèi)容提交到頁面上顯示.// 點擊的時候, 獲取到三個輸入框中的文本內(nèi)容// 創(chuàng)建一個新的 div.row 把內(nèi)容構造到這個 div 中即可.let containerDiv = document.querySelector('.container');let inputs = document.querySelectorAll('input');let button = document.querySelector('#submit');button.onclick = function() {// 1. 獲取到三個輸入框的內(nèi)容let from = inputs[0].value;let to = inputs[1].value;let msg = inputs[2].value;if (from == '' || to == '' || msg == '') {return;}// 2. 構造新 divlet rowDiv = document.createElement('div');rowDiv.className = 'row message';rowDiv.innerHTML = from + ' 對 ' + to + ' 說: ' + msg;containerDiv.appendChild(rowDiv);// 3. 清空之前的輸入框內(nèi)容for (let input of inputs) {input.value = '';}// 4. 把用戶填寫的內(nèi)容, 發(fā)送給服務器. 讓服務器來保存.// $ 是 jquery 提供的全局變量. ajax 就是 $ 的一個方法.// ajax 的參數(shù)是一個 js 對象, 可以有很多屬性let requestBody = {"from": from, // from 變量里的值, 就是第一個輸入框的內(nèi)容, "張三""to": to, // to 變量的值, 就是第二個輸入框的內(nèi)容, "李四""message": msg // msg 變量的值, 就是第三個輸入框的內(nèi)容, "我喜歡你很久了"};// 上述 body 是一個 js 對象, 還需要轉成 json 字符串.let jsonString = JSON.stringify(requestBody);$.ajax({type: 'post',url: 'message',contentType: 'application/json; charset=utf8',data: jsonString,success: function(responseBody) {// 這個回調(diào)就是收到響應之后要執(zhí)行的代碼了.// 前端使用 console.log 打印日志到控制臺. (chrome 開發(fā)者工具的控制臺)console.log("responseBody: " + responseBody);}});}// 直接在 script 里面寫的 js 代碼, 就是在頁面加載時被執(zhí)行到的.// 發(fā)起一個 get 請求, 從服務器獲取到數(shù)據(jù)// get 請求不需要 body, 也就不需要上述 data 和 contentType 屬性了.$.ajax({type: 'get',url: 'message',success: function(body) {// 由于響應中已經(jīng)有 Content-Type: application/json 了, 就不需要使用 parse 方法手動轉換了.// body = JSON.parse(body);// 拿到 container 這個元素let containerDiv = document.querySelector('.container');// 處理服務器返回的響應數(shù)據(jù). (json 格式的數(shù)組了)for (let i = 0; i < body.length; i++) {// body 是一個數(shù)組, 此時 message 也就是 js 對象了.// 這個 message 對象里, 有三個屬性, from, to, messagelet message = body[i];// 根據(jù) message 對象構建 html 片段, 把這個片段給顯示到網(wǎng)頁上.// createElement 方法就能構造出一個 html 標簽.// 此時就得到了 <div></div>let div = document.createElement('div');// 還需要往里面設置一個 屬性 , class="row" (設置這個屬性, 是為了讓 css 能夠給這個元素設置一些樣式)// 此時就得到了 <div class="row"></div>div.className = 'row';// 給這個 div 里設置內(nèi)容// 此時就得到了 <div class="row">張三 對 李四 說: 我喜歡你很久了</div>div.innerHTML = message.from + " 對 " + message.to + " 說: " + message.message;// 把 div 添加到 containerDiv 的末尾containerDiv.appendChild(div);}}});
</script>
</body>
</html>
利用Cookie和Session實現(xiàn)登錄邏輯
Cookie是客戶端存儲數(shù)據(jù)的機制
Session是服務器存儲數(shù)據(jù)的機制(不算持久化存儲)
1.登錄頁面(html)
2.通過一個Servlet處理上述的登錄請求
通過這個Servlet讀取用戶名和密碼,并且驗證是否登錄成功。
如果登陸成功,就會給當前用戶,創(chuàng)建一個會話?,并且把得到的sessionid,通過cooki返回給客戶端,客戶端就把cookie保存起來了。
3.網(wǎng)站主頁,通過另一個servlet生成的動態(tài)頁面
在這個頁面中,就會把剛才這里的用戶數(shù)據(jù)給顯示到頁面上。
getSession(true)
這個方法,就是根據(jù)請求的cookie中的sessionid,查詢服務器的hash表,找到對應的session對象。如果cookie中沒有sessionid(首次登錄的時候,就是沒有的)或者sessionid沒有查找到對應的session對象,就可以創(chuàng)建出一個session對象出來。
參數(shù)為true,允許不存在時自動創(chuàng)建;false不能創(chuàng)建,直接返回null
//可以給會話中保存一些自定義的數(shù)據(jù),通過Attribute的方式來保存 HttpSession session = req.getSession(true); //此處Atrribute也是鍵值對,這里的內(nèi)容存儲什么都可以 session.setAttribute("username",username); session.setAttribute("loginTime",System.currentTimeMillis()); //此處相當于登錄成功,讓頁面跳轉網(wǎng)站首頁 resp.sendRedirect("index");
此處的getSession會創(chuàng)建新會話
1)生成sessionid和HttpSession對象
2)把上述sessionid和HttpSession對象保存到內(nèi)存hash表中
3)把sessionid設置到響應報文的header中的 Set-Cookie字段
瀏覽器拿到響應,就會把這個Set-Cookie的內(nèi)容保存到瀏覽器的Cookie中?。