我想配置我的Spring Boot应用程序,将任何404未找到的请求重定向到我的单页应用程序。
例如,如果我调用的volatile
不存在,则应重定向到localhost:8080/asdasd/asdasdasd/asdasd
。
问题是我有一个单页反应应用程序,它在根路径localhost:8080/notFound
中运行。因此,春季应该重定向到localhost:8080/
,然后转发到localhost:8080/notFound
(以保持路线)。
答案 0 :(得分:17)
这应该可以解决这个问题:为404添加一个路由到/notFound
的错误页面,然后将其转发到SPA(假设条目在/index.html
上):
@Configuration
public class WebApplicationConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/notFound").setViewName("forward:/index.html");
}
@Bean
public EmbeddedServletContainerCustomizer containerCustomizer() {
return container -> {
container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND,
"/notFound"));
};
}
}
答案 1 :(得分:10)
这是完整的Spring Boot 2.0示例:
@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"));
};
}
}
答案 2 :(得分:3)
万一有人在这里迷路寻找如何在Spring Boot应用程序中处理Angular / React /其他路线和路径-但并非总是返回404的index.html-可以在标准Spring控制器RequestMapping中完成。无需添加视图控制器和/或自定义容器错误页面即可完成此操作。
RequestMapping支持通配符,因此您可以使其与应用程序中的一组众所周知的路径(例如,角度路线等)匹配,然后才返回正向index.html:
@Controller
public class Html5PathsController {
@RequestMapping( method = {RequestMethod.OPTIONS, RequestMethod.GET}, path = {"/path1/**", "/path2/**", "/"} )
public String forwardAngularPaths() {
return "forward:/index.html";
}
}
另一种选择(取自Spring的旧文章:https://spring.io/blog/2015/05/13/modularizing-the-client-angular-js-and-spring-security-part-vii)是使用命名约定:
@Controller
public class Html5PathsController {
@RequestMapping(value = "/{[path:[^\\.]*}")
public String redirect() {
return "forward:/index.html";
}
}
以上配置将匹配所有不包含句点且尚未映射到另一个控制器的路径。
答案 3 :(得分:1)
这里是安全配置(SecurityConfig.java)
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private Environment env;
@Autowired
private UserSecurityService userSecurityService;
private BCryptPasswordEncoder passwordEncoder() {
return SecurityUtility.passwordEncoder();
}
private static final String[] PUBLIC_MATCHERS = {
"/css/**",
"/js/**",
"/data/**",
"/sound/**",
"/img/**",
"/",
"/login",
"/logout,
"/error",
"/index2",
};
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().
/* antMatchers("/**").*/
antMatchers(PUBLIC_MATCHERS).
permitAll().anyRequest().authenticated();
//.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login");
http
.csrf().disable().cors().disable()
.formLogin().failureUrl("/login?error")
.defaultSuccessUrl("/index2")
.loginPage("/login").permitAll()
.and()
.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/?logout").deleteCookies("remember-me").permitAll()
.and()
.rememberMe()
.and()
.sessionManagement().maximumSessions(3600)
.and().
invalidSessionUrl("/login");
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userSecurityService).passwordEncoder(passwordEncoder());
}
}
如果未找到任何资源,将重定向到错误页面
@Controller
public class IndexController implements ErrorController{
private static final String PATH = "/error";
@RequestMapping(value = PATH)
public String error() {
return PATH;
}
@Override
public String getErrorPath() {
return PATH;
}
}
错误页面如
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1000/xhtml"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<meta http-equiv="refresh" content="5;url=/login" />
<body>
<h1>Page not found please login the system!</h1>
</body>
</html>
答案 4 :(得分:1)
//add this controller : perfect solution(from jhipster)
@Controller
public class ClientForwardController {
@GetMapping(value = "/**/{path:[^\\.]*}")
public String forward() {
return "forward:/";
}
}
答案 5 :(得分:0)
org.springframework.boot.web.servlet.error.ErrorController 的实现帮了我大忙。我将SpringBoot 2.0与React一起使用。 (如果您对此感兴趣,这是我制作的样板项目:https://github.com/archangel1991/react-with-spring)
@Controller
public class CustomErrorController implements ErrorController {
@Override
public String getErrorPath() {
return "/error";
}
}
我不确定为什么会这样。