背景
在做java端上應用開發的時候,從資源和部署操作成本兩方面考慮,一般會將前端的靜態資源直接與后端應用一起打包,通過springboot內嵌的Tomcat提供web服務。進入web首頁登錄一直到后續業務流程正向操作,頁面都能正常加載靜態資源,但觸發頁面刷新操作的時候,就出現了Whitelabel Error Page,訪問不成功。本文針對此問題做解答。
1. springboot web項目搭建開發
在pom文件中增加thymeleaf依賴
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
配置靜態資源處理器:
public class BaseWebConfig implements WebMvcConfigurer {private LoginInterceptor loginInterceptor;private PermissionInterceptor permissionInterceptor;public List<String> whiteUrl = new ArrayList<>(Arrays.asList("/login","/doLogin","/css/**", // 排除css目錄下的所有資源"/js/**", // 排除js目錄下的所有資源"/images/**", // 排除images目錄下的所有資源"/favicon.ico", // 排除favicon.ico"/static/**" // 排除static目錄下的所有資源));// 登錄攔截器,后端所有的接口都是api/開頭@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(loginInterceptor).addPathPatterns("/api/**").excludePathPatterns(whiteUrl).order(1);}// 靜態資源放到html目錄下@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/**").addResourceLocations("classpath:/html/");}// 默認進入登錄頁@Overridepublic void addViewControllers(ViewControllerRegistry registry) {registry.addViewController("/").setViewName("forward:/index.html");}
}
?配置啟動thymeleaf
spring.thymeleaf.prefix=classpath:/html/
spring.thymeleaf.suffix=.html
spring.thymeleaf.cache=false
靜態文件結構:
|-- src
| ? |--main
| ? | ? |-- resources
| ? | ? |-- application.properties| ? | ? |? ?|-- html
| ? | ? |? ?|? ?|-- index.html
| ? | ? |? ?|? ?|-- app.js
...
2. 問題暴露
訪問后端localhost:8080/login,正常跳轉到登錄頁。登錄成功后,瀏覽器中的地址因為前端自動的路由規則,變成了
localhost:8080/edge?ownerId=jcknuxh&tab=sub1-data-management
看網絡請求也都正常
?
在瀏覽器頁面刷新,直接進入Whitelabel Error Page
查看很多網上的教程,有建議直接攔截所有的請求,轉發到index.html視圖,如下代碼:
@Controller
public class IndexController{@GetMapping("{/path})public String index(@PathVariable String path){return "forward:/index.html";}}
然后就出現了錯誤:
circular view path?
3. 問題解決
解題的思路是參照NGINX加載靜態頁面,當有不識別的頁面的時候,直接跳轉到index.html頁面。Nginx中的配置如下:
server {listen 80;server_name localhost;root /usr/share/nginx/html;index index.html;location / {try_files $uri $uri/ /index.html;}}
?在springboot中怎么配置呢?
// 默認進入登錄頁@Overridepublic void addViewControllers(ViewControllerRegistry registry) {registry.addViewController("/{path;[^\\.]*}").setViewName("forward:/index.html");}
問題就解決了。原理是當遇到不識別的頁面的時候,就跳轉到首頁,首頁有對應的js、css請求路由,從而在刷新頁面的時候,正常渲染。