如果资源未解析,Spring Boot 2.1.0仅提供index.html(SPA,react-router)

时间:2018-11-20 12:34:53

标签: reactjs spring-mvc spring-boot react-router single-page-application

我正在使用具有此配置的Spring Boot 2.1.0为使用create-react-app和react-router制作的SPA提供服务

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/**/{path:[^\\.]+}")
                .setViewName("forward:/");
    }
}

基本上,除非路径中没有句点,否则它始终会提供index.html。我想将其与create-react-app提供的.htaccess对齐。如何使Spring Boot匹配此功能?

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]

3 个答案:

答案 0 :(得分:2)

当找不到其他路线时,您可以像下面一样捕获所有未处理的视图控制器。

@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
       registry.setOrder(Ordered.LOWEST_PRECEDENCE);
        registry.addViewController("/**").setViewName("forward:/index.html");
    }
}

答案 1 :(得分:2)

要将“ 404:找不到文件”重新路由到“转发:/”(我认为这是.htaccess的作用),请将WebMvcConfiguration更改为...

@Configuration
public class WebMvcConfiguration implements ErrorViewResolver
{

    @Override
    public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
        if (status == HttpStatus.NOT_FOUND) {
            return new ModelAndView("forward:/");
        }
        return null;
    }

}

答案 2 :(得分:0)

遵循Kotlin代码可能会有所帮助:

@Configuration
class WebMvcConfig(val resourceProperties: ResourceProperties) : WebMvcConfigurer {

    override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
        registry.addResourceHandler("/**")
            .addResourceLocations(*resourceProperties.staticLocations)
            .resourceChain(resourceProperties.chain.isCache)
            .addResolver(FallbackPathResourceResolver())
    }

    private class FallbackPathResourceResolver : PathResourceResolver() {
        override fun resolveResource(
            request: HttpServletRequest?,
            requestPath: String,
            locations: MutableList<out Resource>,
            chain: ResourceResolverChain
        ): Resource? {
            return super.resolveResource(request, requestPath, locations, chain) ?: super.resolveResource(
                request,
                "/index.html",
                locations,
                chain
            )
        }
    }
}

参考:https://jira.spring.io/browse/SPR-16788