Spring 捕获 index.html 的所有路由
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39331929/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring catch all route for index.html
提问by oli
I'm developing a spring backend for a react-based single page application where I'm using react-router for client-side routing.
我正在为基于 react 的单页应用程序开发 spring 后端,其中我使用 react-router 进行客户端路由。
Beside the index.html page the backend serves data on the path /api/**
.
在 index.html 页面旁边,后端提供路径上的数据/api/**
。
In order to serve my index.html from src/main/resources/public/index.html
on the root path /
of my application I added a resource handler
为了src/main/resources/public/index.html
在/
我的应用程序的根路径上提供我的 index.html,我添加了一个资源处理程序
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/").addResourceLocations("/index.html");
}
What I want to is to serve the index.html page whenever no other route matches, e.g. when I call a path other than /api
.
我想要的是在没有其他路由匹配时为 index.html 页面提供服务,例如,当我调用/api
.
How do I configure such catch-all route in spring?
如何在 spring 中配置这种包罗万象的路由?
回答by Petri Ryh?nen
Since my react app could use the root as forward target this ended up working for me
由于我的反应应用程序可以使用根作为前向目标,这最终对我有用
@Configuration
public class WebConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/{spring:\w+}")
.setViewName("forward:/");
registry.addViewController("/**/{spring:\w+}")
.setViewName("forward:/");
registry.addViewController("/{spring:\w+}/**{spring:?!(\.js|\.css)$}")
.setViewName("forward:/");
}
}
To be honest I have no idea why it has to be exactly in this specific format to avoid infinite forwarding loop.
老实说,我不知道为什么它必须完全采用这种特定格式以避免无限转发循环。
回答by Dan Syrstad
I have a Polymer-based PWA hosted inside of my Spring Boot app, along with static web resources like images, and a REST API under "/api/...". I want the client-side app to handle the URL routing for the PWA. Here's what I use:
我在 Spring Boot 应用程序中托管了一个基于 Polymer 的 PWA,以及静态 Web 资源(如图像)和“/api/...”下的 REST API。我希望客户端应用程序处理 PWA 的 URL 路由。这是我使用的:
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
/**
* Ensure client-side paths redirect to index.html because client handles routing. NOTE: Do NOT use @EnableWebMvc or it will break this.
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// Map "/"
registry.addViewController("/")
.setViewName("forward:/index.html");
// Map "/word", "/word/word", and "/word/word/word" - except for anything starting with "/api/..." or ending with
// a file extension like ".js" - to index.html. By doing this, the client receives and routes the url. It also
// allows client-side URLs to be bookmarked.
// Single directory level - no need to exclude "api"
registry.addViewController("/{x:[\w\-]+}")
.setViewName("forward:/index.html");
// Multi-level directory path, need to exclude "api" on the first part of the path
registry.addViewController("/{x:^(?!api$).*$}/**/{y:[\w\-]+}")
.setViewName("forward:/index.html");
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("classpath:/webapp/");
}
}
This should work for Angular and React apps as well.
这也适用于 Angular 和 React 应用程序。
回答by alexbt
Avoid @EnableWebMvc
避免@EnableWebMvc
By default Spring-Boot serves static content in src/main/resources
:
默认情况下,Spring-Boot 在src/main/resources
以下位置提供静态内容:
- /META-INF/resources/
- /resources/
- /static/
- /public/
- /元信息/资源/
- /资源/
- /静止的/
- /民众/
Or keep @EnableWebMvc and override addViewControllers
或者保留 @EnableWebMvc 并覆盖 addViewControllers
Did you specify @EnableWebMvc
? Take a look a this: Java Spring Boot: How to map my app root (“/”) to index.html?
你指定了@EnableWebMvc
吗?看看这个:Java Spring Boot:如何将我的应用程序根目录(“/”)映射到 index.html?
Either you remove @EnableWebMvc, or you can re-define addViewControllers
:
要么删除@EnableWebMvc,要么重新定义addViewControllers
:
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("forward:/index.html");
}
Or define a Controller to catch /
或者定义一个控制器来捕捉 /
You may take a look a this spring-boot-reactjs sample project on github:
您可以在 github 上查看这个spring-boot-reactjs 示例项目:
It does what you want using a Controller:
它使用控制器执行您想要的操作:
@Controller
public class HomeController {
@RequestMapping(value = "/")
public String index() {
return "index";
}
}
Its index.html
is under src/main/resources/templates
它index.html
在src/main/resources/templates
回答by user3086678
I use react and react-router in my spring boot app, and it was as easy as creating a controller that has mapping to /
and subtrees of my website like /users/**
Here is my solution
我在 Spring Boot 应用程序中使用 react 和 react-router,这就像创建一个控制器一样简单,该控制器具有映射到/
我网站的子树和子树,例如/users/**
Here is my solution
@Controller
public class SinglePageAppController {
@RequestMapping(value = {"/", "/users/**", "/campaigns/**"})
public String index() {
return "index";
}
}
Api calls aren't caught by this controller and resources are handled automatically.
此控制器不会捕获 Api 调用,并且会自动处理资源。
回答by oli
Found an answer by looking at this question
通过查看这个问题找到了答案
@Bean
public EmbeddedServletContainerCustomizer notFoundCustomizer() {
return new EmbeddedServletContainerCustomizer() {
@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/"));
}
};
}
回答by Gandalf
To answer your specific question which involves serving up the Single Page App (SPA) in all cases exceptthe /apiroute here is what I did to modify Petri's answer.
要回答您的特定问题,该问题涉及在所有情况下提供单页应用程序 (SPA),但这里的/api路由是我为修改 Petri 的答案所做的工作。
I have a template named polymer that contains the index.html for my SPA. So the challenge became let's forward all routes except /api and /public-api to that view.
我有一个名为polymer 的模板,其中包含我的SPA 的index.html。所以挑战变成了让我们将除 /api 和 /public-api 之外的所有路由转发到该视图。
In my WebMvcConfigurerAdapter I override addViewControllers and used the regular expression: ^((?!/api/|/public-api/).)*$
在我的 WebMvcConfigurerAdapter 中,我覆盖了 addViewControllers 并使用了正则表达式:^((?!/api/|/public-api/).)*$
In your case you want the regular expression: ^((?!/api/).)*$
在您的情况下,您需要正则表达式:^((?!/api/).)*$
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/{spring:^((?!/api/).)*$}").setViewName("polymer");
super.addViewControllers(registry);
}
This results in being able to hit http://localhostor http://localhost/communityto serve up my SPA and all of the rest calls that the SPA makes being successfully routed to http://localhost/api/posts, http://localhost/public-api/posts, etc.
这导致能够点击http://localhost或http://localhost/community来提供我的 SPA 以及 SPA 成功路由到http://localhost/api/posts 的所有其余调用,http ://localhost/public-api/posts等