我的 Spring 引导配置中有以下内容:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.setOrder(Ordered.HIGHEST_PRECEDENCE)
.addResourceHandler("**/*.*")
.addResourceLocations("file:static/");
}
由于我正在创建一个单页应用程序,我希望此资源处理程序在满足以下条件时提供静态文件:
- 网址不以/api开头
- 此资源处理程序包含与 URL 中的路径匹配的文件
如果没有匹配的文件,则资源处理程序不应使用 404 进行响应,而是让调用通过项目的控制器。
在其中一个中,我将回退到索引.html注释(同样,除非 URL 以/api 开头):
@GetMapping({"/**", "/"})
最后一部分工作正常,但问题是,如果没有匹配的文件,资源处理程序会返回 404,而不是让调用(我习惯了 Node.js 和 Go 的中间件模式)到控制器。我怎样才能做到这一点?我可以创建自己的资源处理程序来充当更像中间件吗?
例如,在Go with Echo中,您只需要为/api启用带有skipper函数的HTML5:
func main() {
server := echo.New()
server.Use(middleware.Static("static"))
server.Use(middleware.StaticWithConfig(middleware.StaticConfig{
Root: "static",
HTML5: true,
Skipper: noHTML5IfAPICallSkipper,
}))
server.Logger.Fatal(server.Start(":1323"))
}
func noHTML5IfAPICallSkipper(context echo.Context) bool {
if strings.HasPrefix(context.Path(), "/api/") {
return true
}
return false
}
如何在 Spring 启动中启用此单页应用程序路由模式?
哦,顺便说一下,静态文件从磁盘而不是从类路径或打包在 jar 内的任何其他内容提供至关重要。此服务将与 Docker 一起运行,并且必须能够从容器外部挂载文件。
试试这个:
public class Application extends WebMvcConfigurerAdapter { // or implements WebMvcConfigurer (Spring Boot 2)
@Value("${static.path}")
private String staticPath;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**/*.*").addResourceLocations("file:"+staticPath);
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("/index.html");
}
...
}
您必须将以下行添加到应用程序属性文件中:
`static.path=path/to/static/content`
如果要使用 Docker,此路径需要引用内部 docker 容器目录,例如:/opt/app/statics
,然后将外部路径映射到此:
您必须将以下行添加到 application.properties 文件中:static.path=/opt/app/statics
并像这样执行 docker:
docker run ... -v /absolute/static/path/at/host:/opt/app/statics image:version