带有Spring Boot的SPA - 为非API请求提供index.html

iru*_*aia 7 spring spring-mvc single-page-application spring-boot

我目前正在开发一个应该使用单页React前端的网页.对于后端,我正在使用spring boot框架.

所有api调用都应使用前缀为url的URL,/api并应由REST控制器处理.

所有其他网址应该只是提供index.html文件.如何用弹簧实现这一目标?

Mac*_*zuk 5

实现您想要的最简单方法是实现自定义404处理程序.

将这些参数添加到您的application.properties:

spring.resources.add-mappings=false
spring.mvc.throw-exception-if-no-handler-found=true
Run Code Online (Sandbox Code Playgroud)

第一个属性删除所有默认的静态资源处理,第二个属性禁用Spring的默认whitelabel页面(默认情况下Spring捕获NoHandlerFoundException并提供标准的whitelabel页面)

将404处理程序添加到应用程序上下文

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.NoHandlerFoundException;
import javax.servlet.http.HttpServletRequest;

@ControllerAdvice
public class PageNotFoundController {
    @ExceptionHandler(NoHandlerFoundException.class)
    public String handleError404() {
            return "redirect:/index.html";
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,您需要添加自定义视图解析程序以提供静态内容(在本例中为index.html)

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceView;
import org.springframework.web.servlet.view.UrlBasedViewResolver;

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/index.html").addResourceLocations("classpath:/static/index.html");
        super.addResourceHandlers(registry);
    }

    @Bean
    public ViewResolver viewResolver() {
        UrlBasedViewResolver viewResolver = new UrlBasedViewResolver();
        viewResolver.setViewClass(InternalResourceView.class);
        return viewResolver;
    }

}
Run Code Online (Sandbox Code Playgroud)

index.html应该被放在/resources/static/目录中.

  • 如果应用程序中存在 SpringSecurity 怎么办?在这种情况下,`NoHandlerFoundException` 甚至不会被解雇。服务器只是抛出 `InsufficientAuthenticationException`。当我简单地用该异常替换`PageNotFoundController` 的`@ExceptionHandler` 注释时,它似乎不起作用。服务器返回 401 未经授权的白标页面。你有什么建议吗? (2认同)