Spring MVC Redirect 傳遞參數完整指南
在 Spring MVC 裡面做 redirect 再常見不過,但怎麼安全地傳遞參數,就有點講究了。之前有個專案因為 redirect 時沒處理好敏感資訊,差點出事。今天就完整介紹幾種傳遞參數的方式。 問題背景假設用戶提交了一個表單,你的 controller 處理完後想要 redirect 到另一個頁面。但有時候你需要傳一些資料給下一個頁面,比如成功/失敗的訊息,或者使用者 ID。 最簡單的方式就是加到 URL query string: 1redirect:/order/confirm?orderId=12345&status=success 但這樣有問題: 敏感資訊會暴露在 URL 上 用戶可以直接改 URL query string 作弊 如果參數很多,URL 會很長很醜 更好的方式是用 RedirectAttributes。 RedirectAttributes 的兩種方式方式一:addAttribute(加到 URL query string)1234567@PostMapping("/order/create")publi...
Spring Cloud Config Client 設定與 @ConfigurationProperties
上一篇文章講了 Config Server 的設定,這篇就來講怎麼在 client 端正確地拉和使用這些設定。有不少人在這邊踩過坑,主要都是因為搞不清楚 bootstrap.yml 和 application.yml 的區別。 bootstrap.yml vs application.yml這是最關鍵的一點,千萬別搞反了。 bootstrap.yml - 用來設定 Spring Cloud 相關的東西,比如 Config Server 的位置。它的載入優先序比 application.yml 更高 application.yml - 普通的應用設定 如果你把 Config Server 的設定寫在 application.yml,Spring 會先載入 application.yml,但這時候還沒有連到 Config Server,所以設定會不全。一定要寫在 bootstrap.yml。 Config Client 的基本設定在你的 Spring Boot 應用裡,先加依賴: 1234<dependency> <groupId>org.sprin...
Spring Cloud Config Server 本地檔案模式設定
Spring Cloud Config 是用來集中管理應用設定的利器,但預設用 Git backend,在開發時有時候有點麻煩。我就來介紹怎麼用本地檔案模式搞定開發環境的設定管理。 為什麼要用本地檔案模式?預設的 Config Server 是用 Git repository 當後端,這對生產環境來說很棒,但開發時有點費事: 要維護一個 Git repo 改設定要 push、pull 不方便快速迭代 用本地檔案模式就簡單多了,直接在電腦上改檔案,重新整理一下就行。 Config Server 的設定首先建立一個 Spring Boot application 當 Config Server。 1. 加依賴1234<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId></dependency> 2. 啟動類別標注 @EnableCo...
ObjectMapper 泛型 JSON 序列化與反序列化
在 Java 裡面用 ObjectMapper(Jackson)處理 JSON 再正常不過了,但一旦涉及到泛型,事情就開始變得有點複雜。我之前在這邊踩過好幾次坑,最後發現居然是反序列化出來的不是我預期的物件。 為什麼泛型會出問題?先說為什麼會有這個問題。Java 的泛型是編譯時的特性,在 runtime 時會被擦除。也就是說,List<MyObj> 和 List<String> 在 runtime 時看起來都是一樣的 List,沒辦法區分。 所以當你這樣寫的時候: 12String json = "[{\"name\": \"Alice\"}, {\"name\": \"Bob\"}]";List<MyObj> list = objectMapper.readValue(json, List.class); Jackson 不知道你想要 List<MyObj>,反序列化出來的就是 List&l...
Spring MVC AOP 設定與 AspectJ 用法
AOP(面向切面編程)這個概念一開始聽起來很唬爛,但其實就是把某些跨越多個業務邏輯的共同功能(比如 logging、權限驗證、效能監控)提取出來,用一個統一的地方來管理。 我之前有個專案就是沒用 AOP,logging 的程式碼散落在各個 service 裡面,後來改用 AOP 重構了一遍,爽度直接升天。 前置準備首先要加上依賴。如果用 Spring Boot,直接加: 1234<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId></dependency> 這個依賴裡面已經包含了 AspectJ 和 Spring AOP 相關的東西。 基本結構用 Spring AOP 的步驟很簡單: 寫一個類別標注 @Aspect 標注 @Component 讓 Spring 掃描到 在方法上標注 @Before、@After 等 定義切入點(point...
Spring Bean Scope 六種作用域完整解析
之前在專案裡因為搞不清楚 Bean scope,導致一個坑埋了好久才發現。乾脆就把 Spring 的六種 scope 整理一下,這樣以後不會再踩到相同的坑。 六種 Scope 速覽Spring Bean 的六種 scope 分別是: singleton - 預設,整個 container 只有一個實例 prototype - 每次 getBean 都新建一個實例 request - 每個 HTTP request 一個實例 session - 每個 HTTP session 一個實例 application - 整個 ServletContext 一個實例 websocket - 每個 WebSocket session 一個實例 後面四種(request、session、application、websocket)只在 web application 中可用。 Singleton 作用域這是預設的 scope。如果你沒有特別指定,Spring 就會把 Bean 當成 singleton: 123456@Componentpublic class UserService ...
Spring @Bean 與 @ComponentScan 的差異
有時候在寫 Spring config 時,新手都會搞不清楚 @Bean 和 @ComponentScan 到底差在哪。我自己也踩過不少坑,今天就來把這兩個概念理清楚。 先說結論簡單講: @Bean 是手動註冊,你明確地在 @Configuration 裡面寫程式碼,告訴 Spring 怎麼建立這個 Bean @ComponentScan 是自動掃描,Spring 自動找出你用 @Component、@Service、@Repository 這些註解標注的類別,然後註冊成 Bean 兩者各有用途,也可以混用。 @Bean 怎麼用@Bean 通常用在 @Configuration class 裡面。你寫一個方法,用 @Bean 標注,Spring 就會把這個方法回傳的物件當成 Bean 註冊進去。 12345678910111213@Configurationpublic class AppConfig { @Bean public DataSource dataSource() { return new DataSourc...
🔁 解決 Java 中的 ABA 問題 — 使用 AtomicStampedReference
❓ 什麼是 ABA 問題?ABA 問題發生在使用 CAS(Compare-And-Swap)時: 執行緒 A 讀到某個變數值為 A 執行緒 B 將該變數從 A ➝ B ➝ A 執行緒 A 再次使用 CAS,認為值沒變,繼續執行,但其實值已變動過! 這會導致程式誤以為狀態未變,但實際上已經被其他執行緒修改過。 🧰 解法:使用 AtomicStampedReferenceJava 提供 AtomicStampedReference<T>,這是一種「附加版本號(stamp)」的原子參考,可以避免 ABA 問題。 它在每次變更時,都會同步更新一個 stamp 值,用來追蹤版本。 🧪 範例程式碼123456789101112131415161718192021222324252627import java.util.concurrent.atomic.AtomicStampedReference;public class AbaProblemSolution { public static void main(String[] args) {...
☕ Java 原子性變數與 CAS 筆記
📌 一、什麼是「原子性變數」與 CAS?在多執行緒環境下,多個執行緒若同時修改同一個變數,容易發生資料競爭。 Java 提供 java.util.concurrent.atomic 套件,裡面有許多「原子操作」的變數類型,例如: AtomicInteger AtomicLong AtomicReference 這些類別提供 非阻塞(non-blocking) 的操作方式,底層就是使用 CAS(Compare-And-Swap,比較並交換) 實作的。 ⚙️ 二、CAS 的核心邏輯CAS 是一種樂觀鎖策略,基本流程如下: 讀取目前值 比對是否與預期值一致 若一致,就更新為新值 若不一致,就放棄(重試或結束) ✅ 優點:不用 synchronized 就能寫出安全的多執行緒操作 ❌ 缺點:高併發時可能需要一直 retry,自旋過多會浪費 CPU 💡 三、實際範例:用 CAS 實作「無鎖計數器」1234567891011121314151617181920212223242526272829303132333435363738import java.util.concu...
從 Identity 欄位極限值看資料庫運作:實戰查詢範例分享
在這篇文章中,我想跟各位分享一個相當有趣又實用的 SQL 查詢範例。這支查詢主要用來檢查資料庫中各個資料表的 Identity 欄位(通常作為主鍵使用)的目前值(last_value),並根據該欄位的資料型態來推算其可能達到的最大極限值。 查詢範例以下就是完整的 SQL 查詢程式碼: 12345678910111213141516SELECT OBJECT_NAME(ic.object_id) AS TableName, ic.name AS IdentityColumn, ic.last_value AS CurrentValue, CASE WHEN ty.name = 'tinyint' THEN 255 WHEN ty.name = 'smallint' THEN 32767 WHEN ty.name = 'int' THEN 2147483647 ...














