๐๏ธ Spring Boot&React์์ ์๋ก ๊ณ ์นจ 404 ์ค๋ฅ ํด๊ฒฐ
React๋ก ๋จ์ผ ํ์ด์ง ์ ํ๋ฆฌ์ผ์ด์ (SPA)์ ๊ฐ๋ฐํ๊ณ Spring Boot๋ฅผ ํตํด ๋ฐฐํฌํ๋ ๊ณผ์ ์์, ์ฌ์ฉ์๋ค์ด ํน์ ํ์ด์ง๋ก ์ด๋ํ ํ ์๋ก๊ณ ์นจ์ ํ๋ฉด 404 ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค. ์ด๋ React์ Spring Boot๊ฐ ๋ผ์ฐํ ์ ์ฒ๋ฆฌํ๋ ๋ฐฉ์์ ์ฐจ์ด์์ ๋น๋กฏ๋ ๋ฌธ์ ๋ก, ๋ง์ ๊ฐ๋ฐ์๊ฐ ๋ง์ฃผํ๋ ํํ ์ด์์ ๋๋ค. ย ๋ฌธ์ ์ํฉ: ์๋ก๊ณ ์นจ ์ 404 ์ค๋ฅ ๋ฐ์ React ์ ํ๋ฆฌ์ผ์ด์ ์์ BrowserRouter๋ฅผ ์ฌ์ฉํ์ฌ ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ๋ผ์ฐํ (Client-Side Routing)์ ์ฒ๋ฆฌํ ๋, ์๋ก๊ณ ์นจ ์ ๋ค์๊ณผ ๊ฐ์ 404 ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. GET https://example.com/purchased-product 404 (Not Found) ์ด ์ํฉ์ ๋ธ๋ผ์ฐ์ ๊ฐ /purchased-product ๊ฒฝ๋ก์ ๋ํ ์์ฒญ์ ์๋ฒ๋ก ๋ณด๋์ง๋ง, Spring Boot ์๋ฒ๊ฐ ํด๋น ๊ฒฝ๋ก๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ์์ง ๋ชปํด 404 Not Found๋ฅผ ๋ฐํํ๊ธฐ ๋๋ฌธ์ ๋ฐ์ํฉ๋๋ค. ย React๋ ํด๋ผ์ด์ธํธ์์ ๋ชจ๋ ๋ผ์ฐํ ์ ์ฒ๋ฆฌํ๋๋ก ์ค๊ณ๋์์ผ๋, ๋ธ๋ผ์ฐ์ ๋ ์๋ก๊ณ ์นจํ๊ฑฐ๋ ์ง์ URL์ ์ ๋ ฅํ์ ๋ ์๋ฒ์ ์์ฒญ์ ๋ณด๋ด๋ ๊ธฐ๋ณธ ๋์์ ๋ฐ๋ฆ ๋๋ค. ๋ฐ๋ผ์ Spring Boot ์๋ฒ๊ฐ ์ด๋ฌํ ์์ฒญ์ ์ ์ ํ ์ฒ๋ฆฌํ์ง ์์ผ๋ฉด ์์ ๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค. ย ๋ฌธ์ ์์ธ: React์ Spring Boot ๋ผ์ฐํ ์ฒ๋ฆฌ ๋ฐฉ์์ ์ฐจ์ด [React์ ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ๋ผ์ฐํ ] React์์ BrowserRouter๋ ๋ธ๋ผ์ฐ์ ์ ์ฃผ์(URL)๋ฅผ ๋ณ๊ฒฝํ์ง๋ง ์ค์ ๋ก ์๋ฒ์ ์์ฒญ์ ๋ณด๋ด์ง ์์ต๋๋ค. ๋์ , ํด๋ผ์ด์ธํธ ์ธก์์ ๋ผ์ฐํ ์ด ์ด๋ฃจ์ด์ง๋ฉฐ, ๊ฒฝ๋ก์ ๋งคํ๋ React ์ปดํฌ๋ํธ๋ฅผ ๋ ๋๋งํฉ๋๋ค. * URL ๋ณ๊ฒฝ์ ๋ธ๋ผ์ฐ์ ์ฃผ์์ฐฝ์์๋ง ์ด๋ฃจ์ด์ง๋๋ค. * React ๋ด๋ถ์์ ์ง์ ๋ ์ปดํฌ๋ํธ๊ฐ ๋ก๋๋ฉ๋๋ค. ย [๋ธ๋ผ์ฐ์ ์ ๊ธฐ๋ณธ ๋์] ๋ฐ๋ฉด, ๋ธ๋ผ์ฐ์ ์์ ์๋ก๊ณ ์นจํ๊ฑฐ๋ URL์ ์ง์ ์ ๋ ฅํ๋ฉด ํด๋น ๊ฒฝ๋ก์ ๋ํ ์์ฒญ์ ์๋ฒ๋ก ๋ณด๋ ๋๋ค. * ์๋ฒ๋ ๊ฒฝ๋ก์ ๋ํด ์ ์๋ ์ฒ๋ฆฌ๊ฐ ์๋ ๊ฒฝ์ฐ, 404 Not Found๋ฅผ ๋ฐํํฉ๋๋ค. * ์ด๋ ์๋ฒ๊ฐ ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ๋ผ์ฐํ ๊ฒฝ๋ก์ ๋ํด ๋ฌด์งํ ์ํ์ด๊ธฐ ๋๋ฌธ์ ๋๋ค. ย React์ ๋ธ๋ผ์ฐ์ ์ ๋์ ์ฐจ์ด๋ฅผ ์ดํดํ์ผ๋, ์ด์ ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ Spring Boot ์ค์ ๋ฐฉ๋ฒ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค. ย ํด๊ฒฐ ๋ฐฉ๋ฒ: Spring Boot์์ React ๊ฒฝ๋ก ์ฒ๋ฆฌํ๊ธฐ Spring Boot ์๋ฒ๊ฐ React ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ชจ๋ ๊ฒฝ๋ก๋ฅผ ์ฒ๋ฆฌํ๋๋ก ์ค์ ํ๋ฉด, ๋ธ๋ผ์ฐ์ ๊ฐ ์๋ฒ๋ก ๋ณด๋ด๋ ๋ชจ๋ ์์ฒญ์ ๋ํด React์ index.html ํ์ผ์ ๋ฐํํ ์ ์์ต๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ๋ธ๋ผ์ฐ์ ๋ React ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ค์ ๋ก๋ํ๊ณ , ํด๋ผ์ด์ธํธ ์ธก์์ ์ฌ๋ฐ๋ฅธ ๊ฒฝ๋ก๋ฅผ ๋ ๋๋งํ ์ ์์ต๋๋ค. ย [๊ตฌํ ๋ฐฉ๋ฒ] Spring Boot์์ React ๋ผ์ฐํ ์ ์ฒ๋ฆฌํ๊ธฐ ์ํ WebController๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์์ฑํ ์ ์์ต๋๋ค. import org.springframework.boot.web.servlet.error.ErrorController; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; @Controller public class WebController implements ErrorController { @GetMapping({ "/purchased-product" }) public String index() { // Spring Boot๊ฐ React์ index.html ํ์ผ์ ๋ฐํํ๋๋ก ์ค์ // index.html์ /resources/static ๋๋ /resources/public์ ์์น return "index.html"; } } ย ์ ์ฝ๋๋ React ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฒฝ๋ก๋ฅผ ๋ช ์์ ์ผ๋ก ๋์ดํ๊ณ , ํด๋น ๊ฒฝ๋ก์ ๋ํ ์์ฒญ์ด ๋ค์ด์ค๋ฉด index.html์ ๋ฐํํ๋๋ก ์ค์ ํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด React์ ๋ผ์ฐํฐ๊ฐ ํด๋ผ์ด์ธํธ ์ธก์์ ๊ฒฝ๋ก๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ ํ๊ฒฝ์ ์ ๊ณตํ๊ฒ ๋ฉ๋๋ค. ย ๊ฒฐ๋ก Spring Boot์ React๋ฅผ ํตํฉํ ๋, ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ๋ผ์ฐํ ์ผ๋ก ์ธํด ๋ฐ์ํ๋ ์๋ก๊ณ ์นจ 404 ์ค๋ฅ๋ React์ ๋ธ๋ผ์ฐ์ ์ ๊ธฐ๋ณธ ๋์ ์ฐจ์ด์์ ๋ฐ์ํฉ๋๋ค. ์๋ฒ์์ React์ ๋ชจ๋ ๊ฒฝ๋ก๋ฅผ ์ฒ๋ฆฌํ๋๋ก ์ค์ ํจ์ผ๋ก์จ ๋ฌธ์ ๋ฅผ ์ฝ๊ฒ ํด๊ฒฐํ ์ ์์ต๋๋ค.