深度解析Java視角下Cookie、Session、Token實戰(zhàn)教程
在Java Web開發(fā)中,用戶身份認證與狀態(tài)保持是核心需求之一。Cookie、Session、Token作為三種主流的狀態(tài)管理機制,貫穿于從傳統(tǒng)JSP/Servlet項目到現(xiàn)代Spring Boot/Cloud微服務架構(gòu)的各類應用中。很多開發(fā)者對三者的區(qū)別、適用場景及底層實現(xiàn)一知半解,本文將從Java技術(shù)棧出發(fā),結(jié)合源碼級解析與實戰(zhàn)案例,全面拆解Cookie、Session、Token的核心邏輯,幫助大家構(gòu)建清晰的知識體系。
一、前置知識:HTTP協(xié)議的無狀態(tài)性
要理解Cookie、Session、Token的設(shè)計初衷,首先要明確HTTP協(xié)議的核心特性——無狀態(tài)性。HTTP協(xié)議本身不保存客戶端與服務器之間的交互狀態(tài),即服務器無法通過HTTP協(xié)議自動識別兩次請求是否來自同一客戶端。例如:用戶第一次訪問服務器登錄成功后,第二次請求時服務器無法直接知曉該用戶已登錄,這就導致無法實現(xiàn)購物車、個人中心等需要狀態(tài)保持的功能。
為了解決HTTP無狀態(tài)性帶來的問題,Cookie、Session、Token應運而生。三者的核心目標都是實現(xiàn)“客戶端身份識別”與“狀態(tài)保持”,但實現(xiàn)思路、存儲位置、安全特性存在本質(zhì)差異。
二、Cookie:客戶端的狀態(tài)載體
2.1 什么是Cookie?
Cookie是服務器發(fā)送給客戶端瀏覽器的一小段文本數(shù)據(jù)(通常不超過4KB),瀏覽器會將其保存到本地(內(nèi)存或磁盤)。之后,客戶端每次向同一服務器發(fā)送請求時,都會自動攜帶該Cookie數(shù)據(jù),從而讓服務器識別出客戶端身份。
從Java Web角度看,Cookie是Servlet規(guī)范中的標準組件,由javax.servlet.http.Cookie類封裝,服務器通過response對象向客戶端寫入Cookie,通過request對象讀取客戶端攜帶的Cookie。
2.2 Cookie的核心原理與Java實現(xiàn)
2.2.1 核心原理
- 客戶端首次請求服務器時,服務器通過HTTP響應頭的
Set-Cookie字段將Cookie數(shù)據(jù)發(fā)送給客戶端; - 客戶端瀏覽器接收后,根據(jù)Cookie的屬性(如過期時間、路徑、域名)保存到本地;
- 客戶端后續(xù)請求同一服務器時,會在HTTP請求頭的
Cookie字段中攜帶本地保存的Cookie數(shù)據(jù); - 服務器解析請求頭中的Cookie數(shù)據(jù),識別客戶端身份并獲取狀態(tài)信息。
2.2.2 Java實戰(zhàn):Cookie的創(chuàng)建與使用
以下是基于Servlet的Cookie核心操作示例,涵蓋Cookie的創(chuàng)建、寫入客戶端、讀取及銷毀:
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
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.io.PrintWriter;
@WebServlet("/cookieDemo")
public class CookieDemoServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
// 1. 讀取客戶端攜帶的Cookie
Cookie[] cookies = request.getCookies();
if (cookies != null) {
out.write("客戶端攜帶的Cookie:
");
for (Cookie cookie : cookies) {
// 獲取Cookie的名稱和值
String name = cookie.getName();
String value = cookie.getValue();
out.write("名稱:" + name + ",值:" + value + "
");
}
} else {
out.write("客戶端首次訪問,未攜帶Cookie
");
}
// 2. 創(chuàng)建Cookie并寫入客戶端
Cookie userCookie = new Cookie("username", "zhangsan");
// 設(shè)置Cookie的過期時間:單位為秒,正數(shù)表示持久化到磁盤,負數(shù)表示僅存于內(nèi)存(會話結(jié)束后銷毀),0表示立即刪除
userCookie.setMaxAge(3600);
// 設(shè)置Cookie的有效路徑:僅當請求路徑匹配該路徑時,才攜帶此Cookie
userCookie.setPath("/");
// 設(shè)置Cookie的有效域名:指定哪些域名可以訪問該Cookie,防止跨域盜用
userCookie.setDomain("localhost");
// 設(shè)置Cookie為HttpOnly:禁止JavaScript讀取,防止XSS攻擊
userCookie.setHttpOnly(true);
// 設(shè)置Cookie為Secure:僅在HTTPS協(xié)議下才攜帶此Cookie
// userCookie.setSecure(true);
// 將Cookie寫入響應
response.addCookie(userCookie);
// 3. 銷毀Cookie(通過設(shè)置maxAge為0實現(xiàn))
Cookie deleteCookie = new Cookie("oldCookie", "");
deleteCookie.setMaxAge(0);
deleteCookie.setPath("/");
response.addCookie(deleteCookie);
out.close();
}
}
2.3 Cookie的核心屬性詳解
屬性名 | 作用 | Java方法 | 注意事項 |
|---|---|---|---|
Name | Cookie的名稱,唯一標識一個Cookie | setName(String name) | 名稱一旦確定,無法修改,只能通過同名Cookie覆蓋 |
Value | Cookie存儲的文本數(shù)據(jù) | setValue(String value) | 不能包含空格、逗號、分號等特殊字符,需URL編碼 |
Max-Age | 過期時間(秒) | setMaxAge(int maxAge) | 默認-1(內(nèi)存存儲),0表示立即刪除,正數(shù)表示持久化 |
Path | 有效路徑,僅匹配路徑的請求才攜帶Cookie | setPath(String path) | 默認是當前Servlet的路徑,設(shè)置為“/”表示整個應用有效 |
Domain | 有效域名,限制Cookie的訪問范圍 | setDomain(String domain) | 例如“example.com”表示子域名(www.example.com)也可訪問 |
HttpOnly | 禁止JavaScript讀取Cookie | setHttpOnly(boolean httpOnly) | 有效防止XSS攻擊,Java EE 6及以上支持 |
Secure | 僅在HTTPS協(xié)議下攜帶Cookie | setSecure(boolean secure) | 提升安全性,生產(chǎn)環(huán)境建議開啟 |
2.4 Cookie的優(yōu)缺點
優(yōu)點
- 實現(xiàn)簡單:基于HTTP標準,Java Servlet原生支持,開發(fā)成本低;
- 減輕服務器壓力:數(shù)據(jù)存儲在客戶端,無需服務器額外存儲;
- 跨請求共享:自動攜帶,無需客戶端手動處理。
缺點
- 容量限制:單個Cookie不超過4KB,多個Cookie總數(shù)有限(不同瀏覽器限制不同,通常20-50個);
- 安全性差:默認可被JavaScript讀?。ㄎ丛O(shè)置HttpOnly時),易遭受XSS攻擊;可能被篡改,需加密處理;
- 數(shù)據(jù)類型限制:僅支持文本數(shù)據(jù),無法存儲復雜對象;
- 跨域限制:受同源策略限制,無法在不同域名間共享(除非特殊配置)。
三、Session:服務器端的狀態(tài)管理
3.1 什么是Session?
Session(會話)是服務器為每個客戶端(瀏覽器)創(chuàng)建的內(nèi)存級狀態(tài)對象,用于存儲客戶端的會話信息(如登錄狀態(tài)、購物車數(shù)據(jù)等)。服務器通過Session ID唯一標識每個Session,而Session ID通常通過Cookie發(fā)送給客戶端,客戶端后續(xù)請求時攜帶Session ID,服務器通過該ID找到對應的Session對象,從而實現(xiàn)狀態(tài)保持。
在Java Web中,Session由Servlet容器(如Tomcat、Jetty)管理,通過javax.servlet.http.HttpSession接口封裝,開發(fā)者無需手動管理Session的創(chuàng)建、銷毀及Session ID的傳遞。
3.2 Session的核心原理與Java實現(xiàn)
3.2.1 核心原理
- 客戶端首次請求服務器時,服務器創(chuàng)建一個Session對象,生成唯一的Session ID;
- 服務器將Session ID通過Cookie(默認名為JSESSIONID)發(fā)送給客戶端;
- 客戶端瀏覽器保存該Cookie(默認Max-Age為-1,僅存于內(nèi)存);
- 客戶端后續(xù)請求時,攜帶JSESSIONID Cookie,服務器通過Session ID查找對應的Session對象,獲取客戶端狀態(tài)。
注意:Session的底層依賴Cookie傳遞Session ID,但也支持URL重寫(將Session ID拼接在URL后)作為Cookie禁用時的替代方案。
3.2.2 Java實戰(zhàn):Session的創(chuàng)建與使用
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;
import java.io.PrintWriter;
import java.util.Date;
@WebServlet("/sessionDemo")
public class SessionDemoServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
// 1. 獲取Session(若不存在則創(chuàng)建新Session)
HttpSession session = request.getSession();
// 獲取Session ID
String sessionId = session.getId();
out.write("Session ID:" + sessionId + "
");
// 獲取Session創(chuàng)建時間
Date createTime = new Date(session.getCreationTime());
out.write("Session創(chuàng)建時間:" + createTime + "
");
// 獲取最后訪問時間
Date lastAccessTime = new Date(session.getLastAccessedTime());
out.write("最后訪問時間:" + lastAccessTime + "
");
// 2. 向Session中存儲數(shù)據(jù)(支持任意Java對象)
session.setAttribute("user", new User("zhangsan", 20));
session.setAttribute("isLogin", true);
// 3. 從Session中讀取數(shù)據(jù)
User user = (User) session.getAttribute("user");
boolean isLogin = (boolean) session.getAttribute("isLogin");
out.write("當前登錄用戶:" + user.getName() + ",年齡:" + user.getAge() + "
");
out.write("登錄狀態(tài):" + (isLogin ? "已登錄" : "未登錄") + "
");
// 4. 設(shè)置Session的過期時間(單位:秒)
// 方式1:通過API設(shè)置(優(yōu)先級高于web.xml配置)
session.setMaxInactiveInterval(1800); // 30分鐘無操作過期
// 方式2:在web.xml中配置(全局生效)
/*
<session-config>
<session-timeout>30</session-timeout> <!-- 單位:分鐘 -->
</session-config>
*/
// 5. 手動銷毀Session(用于退出登錄)
// session.invalidate();
// 6. URL重寫(Cookie禁用時使用)
String url1 = response.encodeURL("/test");
String url2 = response.encodeRedirectURL("/test");
out.write("重寫后的URL:" + url1 + "
");
out.close();
}
// 自定義User類(需實現(xiàn)Serializable接口,支持Session鈍化/活化)
static class User implements java.io.Serializable {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
// getter/setter
public String getName() { return name; }
public int getAge() { return age; }
}
}
3.3 Session的核心機制:鈍化與活化
由于Session默認存儲在服務器內(nèi)存中,當服務器重啟或Session數(shù)量過多時,會導致內(nèi)存溢出或Session丟失。因此,Servlet容器提供了Session鈍化(Passivation)與活化(Activation)機制:
- 鈍化:當Session長時間未被訪問或服務器內(nèi)存緊張時,容器將Session對象序列化到磁盤文件(如Tomcat的work目錄);
- 活化:當客戶端再次請求該Session時,容器將磁盤中的Session文件反序列化為內(nèi)存對象,恢復會話狀態(tài)。
注意:要實現(xiàn)Session鈍化/活化,Session中存儲的對象必須實現(xiàn)java.io.Serializable接口,否則會拋出序列化異常。
3.4 Session的優(yōu)缺點
優(yōu)點
- 安全性高:數(shù)據(jù)存儲在服務器端,客戶端無法直接修改;
- 數(shù)據(jù)類型靈活:支持存儲任意Java對象,無需手動序列化;
- 容量無限制:僅受服務器內(nèi)存限制,可存儲大量會話數(shù)據(jù)。
缺點
- 服務器壓力大:每個會話對應一個內(nèi)存對象,高并發(fā)場景下會占用大量服務器資源;
- 分布式部署問題:Session存儲在單個服務器節(jié)點,分布式架構(gòu)下需要實現(xiàn)Session共享(如Redis集群、Tomcat集群Session復制);
- 依賴Cookie:默認通過Cookie傳遞Session ID,若客戶端禁用Cookie,需使用URL重寫(安全性低且不美觀);
- 狀態(tài)丟失風險:服務器重啟或崩潰時,未鈍化的Session會丟失。
四、Token:無狀態(tài)的身份憑證
4.1 什么是Token?
Token(令牌)是服務器為客戶端生成的加密字符串憑證,包含客戶端身份信息、過期時間等核心數(shù)據(jù)??蛻舳说卿洺晒螅掌魃蒚oken并返回給客戶端,客戶端將Token存儲在本地(Cookie、LocalStorage、SessionStorage等),后續(xù)請求時通過請求頭(如Authorization)攜帶Token,服務器通過解密Token驗證客戶端身份,無需在服務器端存儲會話狀態(tài)。
Token是解決分布式架構(gòu)下Session共享問題的核心方案,主流的Token標準有JWT(JSON Web Token)、OAuth2.0等。在Java開發(fā)中,常用JJWT(Java JWT)庫實現(xiàn)JWT的生成與驗證。
4.2 Token的核心原理(以JWT為例)
JWT由三部分組成,用“.”分隔:Header.Payload.Signature,整體結(jié)構(gòu)如下:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InpoYW5nc2FuIiwiaWF0IjoxNzEzMzM4NzY0LCJleHAiOjE3MTMzNDIzNjR9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
4.2.1 各部分解析
- Header(頭部):指定Token的類型(JWT)和加密算法(如HS256、RS256),示例:
{ "alg": "HS256", // 哈希算法:HMAC SHA256"typ": "JWT" // 令牌類型 }頭部會經(jīng)過Base64URL編碼后作為JWT的第一部分。 - Payload(載荷):存儲核心數(shù)據(jù)(如用戶ID、用戶名、過期時間),分為標準聲明、公共聲明和私有聲明: 示例:
{"username": "zhangsan", // 私有聲明"iat": 1713338764, // 簽發(fā)時間(時間戳)"exp": 1713342364 // 過期時間(時間戳,此處為1小時后)}載荷也會經(jīng)過Base64URL編碼后作為JWT的第二部分(注意:Base64URL編碼是可逆的,因此不要在載荷中存儲敏感信息,如密碼)。 - 標準聲明:JWT規(guī)定的默認字段(可選),如iss(簽發(fā)者)、exp(過期時間)、iat(簽發(fā)時間)、sub(主題)等;
- 公共聲明:自定義的公共字段,可被任意客戶端讀??;
- 私有聲明:客戶端與服務器約定的私有字段,用于存儲業(yè)務相關(guān)信息。
- Signature(簽名):對Header和Payload的編碼結(jié)果進行加密,確保Token不被篡改。加密過程如下:
Signature = HMACSHA256(base64UrlEncode(Header) + "." + base64UrlEncode(Payload),密鑰(secret))服務器通過密鑰驗證簽名的有效性:若Token被篡改,編碼后的Header和Payload會發(fā)生變化,簽名驗證將失敗。
4.2.2 JWT的核心流程
- 客戶端提交用戶名/密碼到服務器登錄接口;
- 服務器驗證 credentials 有效后,生成JWT Token(包含用戶信息和過期時間);
- 服務器將Token返回給客戶端(如JSON響應);
- 客戶端存儲Token(如LocalStorage),后續(xù)請求時在Authorization頭中攜帶:
Authorization: Bearer <Token>; - 服務器接收請求后,解析Token,驗證簽名和過期時間;
- 驗證通過則處理請求,驗證失敗則返回401 Unauthorized。
4.3 Java實戰(zhàn):基于JJWT實現(xiàn)JWT
4.3.1 引入依賴(Maven)
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>4.3.2 實現(xiàn)JWT工具類
/**
* JWT工具類
*/
public class JwtUtil {
//有效期為
public static final Long JWT_TTL = 60 * 60 *1000L;// 60 * 60 *1000 一個小時
//設(shè)置秘鑰明文
public static final String JWT_KEY = "qcby";
/**
* 創(chuàng)建token
* @param id //用戶id
* @param subject // 用戶名
* @param ttlMillis // 有效期
* @return
*/
public static String createJWT(String id, String subject, Long ttlMillis) {
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
if(ttlMillis==null){
ttlMillis=JwtUtil.JWT_TTL;
}
//簽名時間
long expMillis = nowMillis + ttlMillis;
Date expDate = new Date(expMillis);
SecretKey secretKey = generalKey();
JwtBuilder builder = Jwts.builder()
.setId(id) //唯一的ID
.setSubject(subject) // 主題 可以是JSON數(shù)據(jù)
.setIssuer("wd") // 簽發(fā)者
.setIssuedAt(now) // 簽發(fā)時間
.signWith(signatureAlgorithm, secretKey) //使用HS256對稱加密算法簽名, 第二個參數(shù)為秘鑰
.setExpiration(expDate);// 設(shè)置過期時間
return builder.compact();
}
/**
* 生成加密后的秘鑰 secretKey
* @return
*/
public static SecretKey generalKey() {
byte[] encodedKey = Base64.getDecoder().decode(JwtUtil.JWT_KEY);
SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
return key;
}
/**
* 解析
*
* @param jwt
* @return
* @throws Exception
*/
public static Claims parseJWT(String jwt) throws Exception {
SecretKey secretKey = generalKey();
return Jwts.parser()
.setSigningKey(secretKey)
.parseClaimsJws(jwt)
.getBody();
}
public static void main(String[] args) {
String token = JwtUtil.createJWT(UUID.randomUUID().toString(),"qd",null );
System.out.println(token);
}
}4.4 Token的優(yōu)缺點
優(yōu)點
- 無狀態(tài):服務器無需存儲會話狀態(tài),減輕服務器壓力,易于分布式部署;
- 跨域支持:Token通過請求頭攜帶,不受同源策略限制,可用于跨域認證(如前后端分離、微服務架構(gòu));
- 靈活性高:可存儲自定義數(shù)據(jù),支持多種客戶端(瀏覽器、APP、小程序等);
- 安全性可控:通過加密簽名確保不被篡改,支持非對稱加密(如RS256)提升安全性。
缺點
- 無法主動銷毀:Token一旦生成,在過期前始終有效,若需注銷登錄,需在客戶端刪除Token或服務器維護黑名單(增加復雜度);
- 載荷不可靠:Base64URL編碼可逆,不能存儲敏感信息;
- 性能開銷:每次請求都需解密驗證簽名,高并發(fā)場景下會有一定性能損耗(可通過緩存優(yōu)化);
- 實現(xiàn)復雜度高:需手動處理Token的生成、驗證、解析,以及過期刷新機制(Session由容器自動管理)。
五、Cookie、Session、Token核心對比與適用場景
5.1 核心維度對比
對比維度 | Cookie | Session | Token(JWT) |
|---|---|---|---|
存儲位置 | 客戶端(瀏覽器) | 服務器端(內(nèi)存/磁盤) | 客戶端(任意存儲方式) |
數(shù)據(jù)大小 | 單個≤4KB,總數(shù)有限 | 無限制(受服務器內(nèi)存) | 無嚴格限制(建議不超過1KB,避免請求頭過大) |
數(shù)據(jù)類型 | 僅文本 | 任意Java對象 | 文本(JSON格式) |
狀態(tài)管理 | 客戶端狀態(tài) | 服務器端狀態(tài) | 無狀態(tài) |
安全性 | 較低(易被篡改、XSS攻擊) | 較高(數(shù)據(jù)在服務器端) | 中高(簽名驗證,可防篡改) |
分布式支持 | 天然支持(客戶端攜帶) | 需額外實現(xiàn)共享(Redis/集群復制) | 天然支持(無狀態(tài)) |
實現(xiàn)復雜度 | 低(Servlet原生支持) | 低(容器自動管理) | 高(需手動處理生成、驗證、刷新) |
5.2 適用場景推薦
- Cookie適用場景:
- 存儲少量非敏感數(shù)據(jù),如用戶偏好設(shè)置、主題配置;
- 配合Session傳遞Session ID;
- 簡單的身份標識(如記住登錄狀態(tài),需加密)。
- Session適用場景:
- 單體應用(非分布式)的用戶認證與狀態(tài)保持;
- 需要存儲大量會話數(shù)據(jù)的場景(如購物車);
- 對安全性要求較高,且無需跨域的場景。
- Token適用場景:
- 分布式架構(gòu)、微服務架構(gòu)(無需Session共享);
- 前后端分離項目(前端獨立部署,跨域請求);
- 多客戶端認證(瀏覽器、APP、小程序等統(tǒng)一認證);
- 第三方接口授權(quán)(如OAuth2.0協(xié)議)。
六、總結(jié)與最佳實踐
Cookie、Session、Token并非對立關(guān)系,而是互補關(guān)系,核心目標都是解決HTTP無狀態(tài)性帶來的狀態(tài)保持問題。在實際開發(fā)中,需根據(jù)項目架構(gòu)、安全性要求、客戶端類型等因素選擇合適的方案:
- 單體應用優(yōu)先選擇Session:實現(xiàn)簡單,安全性高,容器自動管理,無需手動處理復雜邏輯;
- 分布式/前后端分離應用優(yōu)先選擇Token(JWT):無狀態(tài)特性適配分布式部署,跨域支持好,適合多客戶端;
- Cookie始終作為輔助工具:可用于存儲少量非敏感數(shù)據(jù),或配合Session/Token實現(xiàn)狀態(tài)傳遞(如設(shè)置HttpOnly Cookie存儲Token,提升安全性);
- 安全性最佳實踐:
- Cookie務必設(shè)置HttpOnly和Secure屬性,防止XSS攻擊;
- Session需設(shè)置合理的過期時間,分布式場景下使用Redis實現(xiàn)Session共享;
- Token使用非對稱加密(如RS256),密鑰不要硬編碼,定期輪換;
- 敏感數(shù)據(jù)(如密碼)禁止存儲在Cookie或Token載荷中。
通過本文的講解,相信大家對Cookie、Session、Token的底層邏輯、Java實現(xiàn)及適用場景有了全面的理解。在實際開發(fā)中,需靈活結(jié)合三者的優(yōu)勢,根據(jù)項目需求選擇最優(yōu)方案,同時注重安全性設(shè)計,避免常見的安全漏洞。
到此這篇關(guān)于Java視角下Cookie、Session、Token深度解析與實戰(zhàn)的文章就介紹到這了,更多相關(guān)java cookie、session、token內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java的String類中的startsWith方法和endsWith方法示例詳解
大家應該都知道startsWith()方法用于檢測字符串是否以指定的前綴開始,endsWith()方法用于測試字符串是否以指定的后綴結(jié)束,本文就Java的String類中的startsWith方法和endsWith方法給大家詳細講解,感興趣的朋友一起看看吧2023-11-11
Java中由substring方法引發(fā)的內(nèi)存泄漏詳解
這篇文章主要介紹了Java中由substring方法引發(fā)的內(nèi)存泄漏詳解,涉及substring方法引發(fā)的內(nèi)存泄漏簡介,substring的作用和實現(xiàn)原理等相關(guān)內(nèi)容,具有一定借鑒價值,需要的朋友可以參考下2017-12-12
springboot中RabbitMQ死信隊列的實現(xiàn)示例
死信隊列是一種特殊的消息隊列,用來存儲無法被正常消費的消息,常被用來實現(xiàn)延遲處理,異常消息處理等,本文主要介紹了springboot中RabbitMQ死信隊列的實現(xiàn)示例,感興趣的可以了解一下2024-01-01
Java中ThreadLocal?導致內(nèi)存?OOM?的原因分析
這篇文章主要介紹了Java中ThreadLocal導致內(nèi)存OOM的原因分析,文章基于Java的相關(guān)內(nèi)容展開ThreadLocal導致內(nèi)存OOM的原因分析,需要的小伙v阿布可以參考一下2022-05-05

