配置 Spring Boot 將 404 重新導向到單頁應用程式
1. 引言
使用 React、Angular 或 Vue 等技術建立的單頁應用程式 (SPA) 通常依賴客戶端路由。當後端使用 Spring Boot 時,重新整理頁面或存取錯誤連結會向不存在的伺服器路徑發送請求,Spring Boot 隨後會傳回 404 錯誤。
為了讓 SPA 正常運作,我們需要將所有未符合的請求轉送到index.html ,並傳回 HTTP 狀態碼 200。這樣前端路由器就可以處理路徑了。
在本教程中,我們將學習如何設定 Spring Boot,以便將所有未知路由重新導向至 SPA 的index.html 。
2. Maven 依賴項
首先,讓我們將spring-boot-starter-web依賴項匯入pom.xml檔案中:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.3.2</version>
</dependency>
3. 使用 Spring Boot 建立一個基本的單頁應用程式
我們考慮一個使用 Spring Boot 部署的單頁應用程式 (SPA),其中編譯後的前端檔案放置在resources目錄中:
src/main/resources/static
例如,一個最簡的index.html可能如下所示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Baeldung</title>
</head>
<body>
<h1>Home Page</h1>
</body>
</html>
接下來,我們建立一個簡單的控制器來轉送根路徑:
@Controller
public class HomeController {
@RequestMapping("/")
public String getHome(){
return "forward:/index.html";
}
}
當使用者存取根路徑http://localhost:8080/ , Spring Boot 會正確地提供index.html 。
但是,如果使用者刷新客戶端路由(例如http://localhost:8080/dashboard, Spring Boot 會嘗試尋找/dashboard伺服器映射,並傳回404 Not Found 。我們希望 Spring Boot 返回index.html ,以便 SPA 路由器可以處理該路由。
4. 重定向 404 未找到錯誤
在本節中,我們將介紹一些將不符的請求重定向到index.html的解決方案。
4.1. 使用控制器轉送未知路由
讓我們建立一個控制器,將所有未映射的路徑轉送到index.html :
@Controller
public class SpaForwardController {
@RequestMapping(value = "/{path:[^\\.]*}")
public String redirect() {
return "forward:/";
}
}
沒有檔案副檔名的未匹配請求將被轉發到“/”,這將傳回index.html 。
**如果存在特定的映射(例如, @GetMapping(“/dashboard”) `),Spring 會優先選擇該映射,並忽略通用模式**。對於任何其他沒有符合處理程序的路徑(例如/settings ),請求將傳遞給通用映射並轉發到index.html 。
此外,我們還需要支援更深層的路由,例如/dashboard/settings 。為此,我們可以擴展控制器映射:
@Controller
public class SpaForwardController {
@RequestMapping(value = {
"/{path:[^\\.]*}",
"/{path:[^\\.]*}/**/{subpath:[^\\.]*}"
})
public String redirect() {
return "forward:/";
}
}
4.2. 使用自訂錯誤控制器
另一種方法是攔截 404 錯誤並將其重定向到 SPA 入口點:
@Controller
public class SpaErrorController implements ErrorController {
@RequestMapping("/error")
public String handleError() {
return "forward:/index.html";
}
}
這種方法確保任何未知的路由最終都能載入 SPA。
然而,這種方法也可能攔截到真正的後端 404 錯誤,這可能並不總是我們所希望的。
4.3. 使用WebMvcConfigurer
另一種方法是集中處理錯誤,避免明確匹配路由模式。
我們可以透過實作WebMvcConfigurer介面並註冊自訂錯誤頁面來實現這一點:
@Configuration
public class WebApplicationConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/notFound")
.setViewName("forward:/index.html");
}
@Bean
public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> containerCustomizer() {
return container -> {
container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/notFound"));
};
}
}
在此配置中,任何導致404 Not Found錯誤的請求都會重定向到/notFound 。然後,此端點會將請求轉送至index.html 。
然而,這也意味著所有 404 錯誤(包括來自後端 API 的錯誤)都會重新導向到 SPA,這可能並不總是理想的。
5. 測試
啟動 Spring Boot 應用程式後,我們可以透過造訪不同的 URL 來驗證配置。
首先,我們請求根路徑:
$ curl -i http://localhost:8080/
回應回傳200以及index.html的內容:
HTTP/1.1 200
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Baeldung</title>
</head>
<body>
<h1>Home Page</h1>
</body>
</html>
接下來,我們模擬訪問客戶端路由:
$ curl -i http://localhost:8080/dashboard
應用程式沒有回傳404 Not Found ,而是傳回200狀態碼並提供index.html 。這證實了請求已被 SPA 路由器轉送和處理。
6. 結論
本文探討了在使用 Spring Boot 提供單頁應用程式時,如何將未知路由轉送至index.html 。我們研究了多種方法,包括使用自訂控制器、設定WebMvcConfigurer以及透過自訂錯誤映射處理錯誤。
和往常一樣,原始碼可以在 GitHub 上找到。