構建安全的REST API:OAuth2和JWT實踐

引言

大家好,我是小黑,小黑在這里跟咱們聊聊,為什么REST API這么重要,同時,為何OAuth2和JWT在構建安全的REST API中扮演著不可或缺的角色。

想象一下,咱們每天都在使用的社交媒體、在線購物、銀行服務等等,它們背后都離不開REST API的支撐。API允許不同的系統和服務之間進行數據交換和通信,正因為有了它,才能讓咱們享受到如此便捷的數字生活。

但是,隨著技術的發展,安全問題也隨之而來。一個沒有加密的API就像是一個沒有鎖的門,任何人都可以隨意進入。這時候,OAuth2和JWT就像是一把鑰匙和一把鎖,確保只有授權的人才能通過這扇門。OAuth2提供了一個全面的授權框架,而JWT(Json Web Token)則用于安全地在各方之間傳遞信息。

REST API簡介

說到REST API,咱們先來搞清楚幾個概念。REST(Representational State Transfer)是一種設計風格,它定義了一套規則,用于創建網絡服務。通過使用HTTP協議的方法,如GET、POST、PUT、DELETE等,REST API允許應用程序或服務訪問網絡上的資源。

舉個例子,假如小黑現在要開發一個天氣預報應用。這個應用需要從一個天氣服務提供商那里獲取數據。這時候,REST API就是小黑和天氣服務提供商之間的橋梁。小黑可以發送一個GET請求到天氣服務的API,請求特定城市的天氣數據,然后這個服務就會返回一個包含天氣信息的JSON響應。

// Java代碼示例:使用HttpClient發送GET請求獲取天氣數據
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;public class WeatherApiClient {public static void main(String[] args) {HttpClient client = HttpClient.newHttpClient();HttpRequest request = HttpRequest.newBuilder().uri(URI.create("https://api.weather.com/v1/city?name=北京")).build();client.sendAsync(request, HttpResponse.BodyHandlers.ofString()).thenApply(HttpResponse::body).thenAccept(System.out::println).join();}
}

這段代碼簡單地展示了如何使用Java的HttpClient發送一個GET請求到天氣服務的API,并異步地獲取響應數據。注意,上面的URL是假設的,實際應用中需要替換成真實的API地址。

通過這個簡單的例子,咱們可以看到,REST API使得從不同的服務獲取數據變得非常簡單和直接。但是,當涉及到敏感信息或者數據需要保護時,單純的REST API就顯得力不從心了。這就是OAuth2和JWT登場的時機,它們可以幫助咱們構建既強大又安全的API服務。

認識OAuth2

在聊OAuth2之前,小黑得先跟咱們解釋一下什么是授權。簡單來說,授權就是賦予某人或某系統某種權限,比如訪問資源的權限。在網絡里,授權確保只有被允許的人或系統能訪問敏感信息或執行重要操作。這就是OAuth2發光發熱的地方。

OAuth2,全名是Open Authorization 2.0,是一個行業標準的授權框架。它允許用戶提供一個令牌給第三方應用,而不是直接暴露用戶的登錄信息,從而安全地授權第三方應用訪問用戶在某一服務上的信息。想象一下,當小黑想要讓一個日歷應用訪問他的郵箱賬戶來同步日程時,OAuth2就能派上用場。

小黑偷偷告訴你一個生財信息差網站: 小黑的生財資料站

OAuth2的四種授權模式

OAuth2定義了四種授權模式,每種模式適用于不同的場景:

  1. 授權碼模式(Authorization Code):這是最常用的模式,適用于有服務器的Web應用。它通過用戶代理重定向來獲得授權碼,然后交換令牌。

  2. 隱式模式(Implicit):適用于沒有后端服務器的純前端應用,如單頁應用(SPA)。它直接在客戶端獲得令牌,而不是授權碼。

  3. 密碼模式(Resource Owner Password Credentials):在用戶信任客戶端的情況下使用,如用戶的設備上的應用。用戶直接提供用戶名和密碼給客戶端,客戶端使用這些信息獲得令牌。

  4. 客戶端憑證模式(Client Credentials):適用于客戶端訪問自己保護的資源,不涉及用戶,通過客戶端的憑證直接獲取令牌。

下面,小黑用Java代碼示例來說明如何實現授權碼模式,因為這是最常見且最安全的一種模式:

// Java代碼示例:使用Spring框架實現OAuth2授權碼模式
// 注意:這是一個高度簡化的示例,實際應用中需要更完整的配置import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;@EnableWebSecurity
public class OAuth2SecurityConfig {protected void configure(HttpSecurity http) throws Exception {http.oauth2Login().authorizationEndpoint().baseUri("/oauth2/authorize").and().redirectionEndpoint().baseUri("/oauth2/callback/*").and().tokenEndpoint().accessTokenResponseClient(accessTokenResponseClient()).and().userInfoEndpoint().userService(customOAuth2UserService());}// 配置訪問令牌的響應客戶端和用戶信息服務...
}

這段代碼是在使用Spring Security和Spring Boot時配置OAuth2授權碼模式的一個基本示例。它定義了授權端點、重定向端點以及令牌端點。需要注意的是,為了實現OAuth2授權碼模式,還需要注冊OAuth2客戶端詳情和配置用戶信息服務,這里因篇幅限制,就不展開了。

通過授權碼模式,應用程序可以安全地獲得用戶授權,而不需要用戶分享他們的用戶名和密碼。這種方式不僅提升了安全性,還提升了用戶體驗,因為用戶可以細粒度地控制第三方應用訪問自己數據的權限。

深入理解JWT

在OAuth2為咱們提供了一個強大的授權框架后,接下來小黑要跟咱們聊聊JWT,一個在安全傳輸信息方面非常關鍵的技術。JWT,全稱是JSON Web Token,它是一個開放標準(RFC 7519),定義了一種緊湊且自包含的方式,用于在各方之間安全地傳輸信息作為JSON對象。因為信息是數字簽名的,所以這種方式是安全的。

JWT的結構

JWT通常由三部分組成,用點(.)分隔開:Header(頭部)、Payload(負載)和Signature(簽名)。

  1. Header:頭部通常由兩部分組成,令牌的類型(即"JWT")和所使用的簽名算法,如HMAC SHA256或RSA。

  2. Payload:負載部分包含了所要傳輸的信息,這些信息以稱為聲明(Claim)的鍵值對形式存在。聲明有三種類型:注冊的聲明、公共的聲明和私有的聲明。

  3. Signature:為了創建簽名部分,你必須取頭部的編碼、負載的編碼,加上一個密鑰,然后通過頭部中指定的算法進行簽名。

使用Java生成和驗證JWT

下面,小黑用Java代碼示例來演示如何生成和驗證一個JWT。咱們將使用java-jwt庫來完成這項工作,這是處理JWT的一個流行Java庫。

首先,咱們需要添加java-jwt依賴到項目中:

<!-- pom.xml -->
<dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>3.8.3</version>
</dependency>

然后,咱們來看看如何生成一個簡單的JWT:

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import java.util.Date;public class JwtDemo {public static void main(String[] args) {// 創建JWTString token = JWT.create().withIssuer("小黑").withSubject("JWT示例").withExpiresAt(new Date(System.currentTimeMillis()+3600*1000)) // 設置過期時間.withClaim("name", "咱們的用戶").sign(Algorithm.HMAC256("secret")); // 使用HMAC256算法,"secret"是密鑰System.out.println("生成的JWT: " + token);}
}

這個示例展示了如何使用java-jwt庫來生成一個JWT。咱們在JWT中設置了發布者、主題、過期時間以及一個自定義聲明。然后使用HMAC256算法和一個密鑰來對其進行簽名。

接下來,看看如何驗證這個JWT:

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;public class JwtVerifyDemo {public static void main(String[] args) {try {Algorithm algorithm = Algorithm.HMAC256("secret"); // 使用相同的密鑰和算法JWTVerifier verifier = JWT.require(algorithm).withIssuer("小黑").build(); // 創建JWT驗證器// 驗證JWTverifier.verify("這里是之前生成的JWT");System.out.println("JWT驗證成功!");} catch (JWTVerificationException exception){// 無效的簽名/聲明System.out.println("JWT驗證失敗: " + exception.getMessage());}}
}

這段代碼演示了如何驗證一個JWT。咱們使用相同的密鑰和算法來創建一個JWTVerifier對象,然后調用其verify方法來驗證JWT。如果JWT的簽名或聲明不匹配,這個方法將拋出一個JWTVerificationException異常。

通過這樣的方式,JWT提供了一個非常靈活且安全的方法來在不同服務之間傳遞信息。

OAuth2與JWT結合的實踐

現在咱們已經分別了解了OAuth2和JWT,接下來小黑要介紹的是,這兩個技術如何結合起來,為REST API提供更加強大和安全的認證和授權機制。

結合OAuth2和JWT的好處

OAuth2提供了一個強大的授權框架,而JWT則為信息的安全傳輸提供了保障。當將它們結合使用時,咱們不僅能實現安全的授權流程,還能確保授權信息的安全傳輸和驗證。這種結合使用的方式,使得系統既能利用OAuth2進行靈活的授權,又能通過JWT確保傳輸數據的完整性和安全性。

實現流程
  1. 用戶認證:用戶首先通過OAuth2的授權碼模式或其他模式進行認證。
  2. 獲取令牌:一旦用戶認證成功,授權服務器會發放一個由JWT構成的訪問令牌給客戶端。
  3. 資源訪問:客戶端隨后可以使用這個JWT令牌來訪問受保護的資源。
代碼實踐:使用Spring Security和JWT

假設小黑正在使用Spring Boot和Spring Security來構建一個REST API,下面是一個簡化的示例,展示如何結合OAuth2和JWT來保護這個API。

首先,咱們需要添加Spring Security和JWT的依賴到項目中:

<!-- pom.xml -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>3.8.3</version>
</dependency>

然后,配置Spring Security來使用JWT:

import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.oauth2Login() // 啟用OAuth2登錄.and().authorizeRequests().anyRequest().authenticated() // 所有請求都需要認證.and().oauth2ResourceServer().jwt(); // 使用JWT作為OAuth2資源服務器的令牌}
}

這段配置確保了所有請求都必須經過認證,并且指定了使用JWT作為資源服務器的認證令牌。

生成和驗證JWT

接下來,小黑要展示如何在授權服務器上生成JWT令牌,并在資源服務器上驗證這個令牌。這里簡化處理,只展示生成令牌的關鍵步驟:

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import java.util.Date;public class TokenProvider {public String createToken() {return JWT.create().withSubject("用戶ID或其他標識").withExpiresAt(new Date(System.currentTimeMillis() + 3600 * 1000)) // 1小時后過期.sign(Algorithm.HMAC256("secret")); // 使用密鑰簽名}
}

在資源服務器上,咱們需要驗證JWT令牌的有效性。可以使用Spring Security的JWT支持來實現這一點,具體配置和實現方式可能會根據實際情況和框架版本有所不同。

通過這樣的實現,小黑和咱們就能構建出一個既安全又靈活的REST API,不僅能有效管理和授權用戶訪問,還能確保數據在傳輸過程中的安全性。這種OAuth2結合JWT的做法,在現代應用開發中越來越成為標配。

安全實踐與策略

在OAuth2和JWT為咱們構建了一個安全框架的基礎上,小黑接下來要和咱們聊聊如何進一步加固REST API的安全性。畢竟,安全是一個永遠在路上的話題,需要咱們持續關注和改進。

防范常見的安全威脅
  1. 跨站請求偽造(CSRF):CSRF攻擊利用了用戶已登錄的認證狀態,讓攻擊者能夠以用戶的名義執行惡意操作。為了防范CSRF,咱們可以利用Spring Security提供的CSRF保護機制,它會要求所有狀態改變的請求(例如POST請求)都必須攜帶一個正確的CSRF令牌。

  2. 跨站腳本攻擊(XSS):XSS攻擊通過在頁面中注入惡意腳本,來竊取用戶數據或者偽造用戶行為。防范XSS的一個有效方法是確保所有用戶輸入都經過適當的清理和轉義,防止惡意腳本的執行。

  3. 安全通信:使用HTTPS而不是HTTP,可以保護咱們的數據在傳輸過程中不被竊聽或篡改。確保所有的通信都通過SSL/TLS加密,是保護REST API安全的基本要求。

使用OAuth2和JWT的最佳安全實踐
  1. 安全存儲密鑰:在使用JWT時,密鑰的安全存儲至關重要。不管是對稱密鑰還是非對稱密鑰,都應該安全存儲,防止被泄露。

  2. 設置合理的令牌過期時間:為了降低令牌被盜用的風險,應該為訪問令牌設置一個合理的過期時間。短期的訪問令牌加上長期的刷新令牌,是一個比較推薦的做法。

  3. 限制令牌的使用范圍:通過限制令牌的使用范圍(Scope),可以減少如果令牌被泄露時可能造成的損害。比如,一個僅用于讀取信息的令牌,就不應該有修改或刪除信息的權限。

  4. 檢查和驗證所有請求:所有到達服務器的請求都應該經過檢查和驗證,確保它們都攜帶了有效的令牌,并且令牌中的權限與請求的操作相匹配。

技術示例:防范CSRF和使用HTTPS

為了更具體地展示如何實施這些安全措施,小黑在這里提供一些技術示例。

防范CSRF

在Spring Security中,CSRF保護默認是開啟的。但是,如果你的應用是一個REST API,通常會禁用CSRF保護,因為API主要使用令牌認證而非Cookie。如果選擇啟用,可以這樣配置:

import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.csrf().disable() // 對于REST API,通常推薦禁用CSRF保護.authorizeRequests().anyRequest().authenticated().and().httpBasic();}
}

技術棧和工具

推薦的Java框架和庫
  1. Spring Security:這是一個功能強大的安全框架,為基于Spring的應用程序提供聲明式的安全訪問控制解決方案。它支持OAuth2和JWT,非常適合用來構建安全的REST API。

  2. java-jwt:這個庫提供了一種簡單的方式來創建和驗證JWT令牌。它支持多種算法,易于集成和使用。

  3. JJWT:這是另一個處理JWT的流行Java庫,它同樣提供了創建和驗證JWT的功能,使用簡單,靈活性高。

實用工具和資源

在開發和調試安全的REST API時,以下工具和資源非常有幫助:

  1. Postman:這是一個強大的API測試工具,允許咱們發送各種HTTP請求,設置請求頭,包括Authorization頭,非常適合測試咱們的OAuth2和JWT實現。

  2. OpenSSL:這是一個強大的加密工具,可以用來生成密鑰和證書,對于設置HTTPS和生成JWT所需的密鑰非常有用。

  3. Let’s Encrypt:這是一個免費的、自動化的、開放的證書頒發機構(CA),提供了一個簡單的方式來安裝SSL/TLS證書,從而啟用HTTPS。

  4. OAuth 2.0 and OpenID Connect:理解OAuth 2.0和OpenID Connect的最佳實踐非常重要,這些知識可以幫助咱們更好地理解和實施安全措施。

技術示例:使用Spring Security和java-jwt

為了具體展示如何使用這些技術棧和工具,小黑提供一個簡單的示例,展示如何使用Spring Security和java-jwt生成JWT令牌:

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;import java.util.Collections;
import java.util.Date;public class JwtUtil {private static final String SECRET = "非常秘密的密鑰";private static final long EXPIRATION_TIME = 864_000_000; // 10天public static String generateToken(Authentication auth) {User principal = (User) auth.getPrincipal();return JWT.create().withSubject(principal.getUsername()).withExpiresAt(new Date(System.currentTimeMillis() + EXPIRATION_TIME)).sign(Algorithm.HMAC512(SECRET.getBytes()));}public static Authentication getAuthentication(String token) {String user = JWT.require(Algorithm.HMAC512(SECRET.getBytes())).build().verify(token).getSubject();return new UsernamePasswordAuthenticationToken(user, null, Collections.singletonList(new SimpleGrantedAuthority("USER")));}
}

這段代碼展示了如何使用java-jwt庫生成和驗證JWT令牌。通過簡單的配置和代碼示例,小黑希望能幫助咱們快速理解和實踐如何在Java應用中使用OAuth2和JWT來保護REST API。

通過掌握這些技術棧和工具,加上前面章節介紹的知識和實踐,咱們就能構建出既強大又安全的REST API服務。這不僅能保護咱們的數據安全,還能提升用戶的信任和滿意

總結

經過前面幾章的探討和學習,小黑和咱們一起走過了構建安全REST API的旅程,從基本的概念到實踐,再到進階的安全策略和技術棧的應用。通過這個過程,咱們不僅學會了如何使用OAuth2和JWT保護REST API,還了解了如何防范常見的安全威脅,并掌握了一些實用的工具和資源。

在現代的應用開發中,安全性是一個不能忽視的話題。隨著技術的發展和攻擊手段的不斷進化,保護好咱們的應用和用戶數據變得越來越重要。OAuth2和JWT提供了一種有效的方式來保護REST API,但這只是安全領域廣闊知識體系中的一部分。安全是一個需要持續學習和實踐的過程,隨著時間的推移,咱們需要不斷更新知識,掌握新的技術和策略。


更多推薦

詳解SpringCloud之遠程方法調用神器Fegin

掌握Java Future模式及其靈活應用

小黑整的視頻會園優惠站

小黑整的生財資料站

使用Apache Commons Chain實現命令模式

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/717839.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/717839.shtml
英文地址,請注明出處:http://en.pswp.cn/news/717839.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

file-upload-download

方式一 情況1&#xff1a; PostMapping("/download1")public ResponseEntity<byte[]> download1() throws Exception {// 下載文件目錄位置FileInputStream fis new FileInputStream("C:\\Users\\wsd\\Pictures\\susu.jpg");// 一次讀取bytes.leng…

Sqli-labs靶場第16關詳解[Sqli-labs-less-16]自動化注入-SQLmap工具注入

Sqli-labs-Less-16 #自動化注入-SQLmap工具注入 SQLmap用戶手冊&#xff1a;文檔介紹 - sqlmap 用戶手冊 以非交互式模式運行 --batch 當你需要以批處理模式運行 sqlmap&#xff0c;避免任何用戶干預 sqlmap 的運行&#xff0c;可以強制使用 --batch 這個開關。這樣&#xff0…

【視頻編碼\VVC】多樣化視頻編碼工具了解

除了通用編碼工具&#xff0c;VVC還針對特定特性的全景視頻、屏幕視頻開發了特定的編碼工具。 全景視頻編碼 360度全包圍視角的球面視頻。為了采用傳統的視頻編碼&#xff0c;全景視頻需要轉換為平面視頻&#xff0c;經緯度等角映射&#xff08;ERF&#xff09;、立方體映射&…

PostgreSQL操作筆記

基礎操作 數據庫相關 -- 查看所有數據庫 \l-- 切換到指定數據庫 \c 庫名-- 查看庫中所有表 \d執行SQL腳本 如果有現成的SQL腳本&#xff1a; \i 腳本路徑路徑一般需要用單引號引起來。 如果需要當場編輯一次性的SQL腳本&#xff0c;可以&#xff1a; \e執行上述命令后會進…

GC機制以及Golang的GC機制詳解

要了解Golang的GC機制,就需要了解什么事GC,以及GC有哪幾種實現方式 一.什么是GC 當一個電腦上的動態內存不再需要時&#xff0c;就應該予以釋放&#xff0c;以讓出內存&#xff0c;這種內存資源管理&#xff0c;稱為垃圾回收&#xff08;Garbage Collection&#xff09;&#x…

最長上升子序列(LIS)簡介及其例題分析

一.最長上升子序列&#xff08;LIS&#xff09;的相關知識 1.最長上升子序列&#xff08;Longest Increasing Subsequence&#xff09;&#xff0c;簡稱LIS&#xff0c;也有些情況求的是最長非降序子序列&#xff0c;二者區別就是序列中是否可以有相等的數。假設我們有一個序…

【論文筆記】Initializing Models with Larger Ones

Abstract 介紹權重選擇&#xff0c;一種通過從預訓練模型的較大模型中選擇權重子集來初始化較小模型的方法。這使得知識從預訓練的權重轉移到更小的模型。 它還可以與知識蒸餾一起使用。 權重選擇提供了一種在資源受限的環境中利用預訓練模型力量的新方法&#xff0c;希望能夠…

代碼隨想錄Day67 | 695.島嶼的最大面積 1020.飛地的數量

代碼隨想錄Day67 | 695.島嶼的最大面積 1020.飛地的數量 695.島嶼的最大面積1020.飛地的數量 695.島嶼的最大面積 文檔講解&#xff1a;代碼隨想錄 視頻講解&#xff1a; 狀態 采用bfs&#xff0c;這道題相較于之前的題變為了求島嶼的最大面積。那就說明我們每遇到一個新的島嶼…

【Linux】軟件管理yum | 編輯器vim | vim插件安裝

目錄 1. Linux軟件管理yum 1.1 什么是軟件包 1.2 查看軟件包 1.3 如何安裝軟件 1.4 如何卸載軟件 2. Linux編輯器vim 2.1 vim的基本概念 2.2 vim的基本操作 2.3 vim正常模式命令集 2.4 vim末行模式命令集 2.5 簡單vim配置 2.6 插件安裝 1. Vim-Plug 3. coc.nvim …

如何自己系統的學python

學習Python是一項很好的投資&#xff0c;因為它是一種既強大又易于學習的編程語言&#xff0c;適用于多種應用&#xff0c;如數據分析、人工智能、網站開發等。下面是一個系統學習Python的步驟建議&#xff1a; 基礎準備 安裝Python&#xff1a; 訪問Python官網下載最新版本的…

微服務獲取當前登錄用戶信息

一&#xff0c;實現思路 1&#xff0c;基于JWT令牌登陸方式 JWT實現登錄的&#xff0c;登錄信息就保存在請求頭的token中。因此要獲取當前登錄用戶&#xff0c;只要獲取請求頭&#xff0c;解析其中的token。 1&#xff09;&#xff0c;Gateway網關攔截&#xff0c;解析用戶信…

微信小程序-生命周期

頁面生命周期 onLoad: 頁面加載時觸發的方法&#xff0c;在這個方法中可以進行頁面初始化的操作&#xff0c;如獲取數據、設置頁面狀態等。 onShow: 頁面顯示時觸發的方法&#xff0c;在用戶進入頁面或從其他頁面返回該頁面時會調用此方法。可以在此方法中進行頁面數據刷新、動…

Onenote軟件新建筆記本時報錯:無法在以下位置新建筆記本

報錯現象&#xff1a; 當在OneNote軟件上&#xff0c;新建筆記本時&#xff1a; 然后&#xff0c;嘗試重新登錄微軟賬戶&#xff0c;也不行&#xff0c;提示報錯&#xff1a; 解決辦法&#xff1a; 打開一個新的記事本&#xff0c;復制粘貼以下內容&#xff1a; C:\Users\Adm…

Mysql中的事務

什么是事務&#xff1a; 多條sql語句&#xff0c;要么全部成功&#xff0c;要么全部失敗。 事務的特性&#xff1a; 1&#xff1a;原子性(Atomic)&#xff1a; 組成一個事務的多個數據庫操作是一個不可分割的原子單元&#xff0c;只有所有操作都成功&#xff0c;整個事務才會…

在Unity中模擬實現手勢識別功能

在虛擬現實(VR)和增強現實(AR)的應用開發中&#xff0c;手勢識別技術扮演著至關重要的角色&#xff0c;它允許用戶以自然的方式與虛擬世界進行交云。然而&#xff0c;并非所有開發者都有條件使用真實的手勢識別硬件。本文介紹了如何在Unity中通過模擬的方式實現一個簡單的手勢識…

【LeetCode】1768_交替合并字符串_C

題目描述 給你兩個字符串 word1 和 word2 。請你從 word1 開始&#xff0c;通過交替添加字母來合并字符串。如果一個字符串比另一個字符串長&#xff0c;就將多出來的字母追加到合并后字符串的末尾。 返回 合并后的字符串 。 https://leetcode.cn/problems/merge-strings-al…

C++調用lua函數

C 調用Lua全局變量(普通) lua_getglobal(lua, "width");int width lua_tointeger(lua,-1);lua_pop(lua,1);std::cout << width << std::endl;lua_close(lua); 這幾行代碼要放到lua_pcall(lua, 0,0,0);之后才可以. C給lua傳遞變量 lua_pushstring(lua, …

Python 操作 Excel,如何又快又好?

?數據處理是 Python 的一大應用場景&#xff0c;而 Excel 則是最流行的數據處理軟件。因此用 Python 進行數據相關的工作時&#xff0c;難免要和 Excel 打交道。Python處理Excel 常用的系列庫有&#xff1a;xlrd、xlwt、xlutils、openpyxl ?xlrd &#xff0d; 用于讀取 Exce…

點云從入門到精通技術詳解100篇-基于點云網絡和 PSO 優化算法的手勢估計(續)

目錄 3 深度圖像處理及轉化 3.1 雙目深度攝像原理及深度圖的獲取 3.1.1 理想化雙目深度相機成像

day47_servlet

今日內容 0 復習昨日 1 接收請求 2 處理響應 0 復習昨日 HTTP請求中 請求行 請求方法,請求路徑 請求頭 頁面信息 請求正文 請求的數據 HTTP響應中 響應行 狀態碼 信息 響應頭 頁面信息 響應正文 要給瀏覽器的內容 1 接收請求 瀏覽器發出請求,經過web.xml映射匹配,找到Servlet…