带有子路径的Spring应用上下文设置
带有子路径的Spring应用上下文设置
在开发中,程序员往往启动应用能跑就好了,但到了线上环境,应用不一定能够分配到一个域名,从而需要在 URL 上设置前缀
1 | www.example.com/spring-app |
对于该情况网络上通常使用 Nginx 进行反向代理,一个示范配置如下
1 | # nginx |
问题
该配置基本能够满足常见应用的需求,但却仍有缺憾,虽然大多数 api 已经被成功代理,但少数依赖于 ContextPath 对象的方法将发生意料外的行为
因为此时应用的server.servlet.context-path
按默认配置为/
,按对外部来讲却是/spring-app/
,这将导致以下几种常见现象
- api 间有重定向行为,但重定向到了以
/
为基准的路径上,但因为 nginx 反向代理,导致地址错误 - 静态资源加载依赖于 ContextPath,但此时 ContextPath 为
/
导致资源未正常加载
解决方法
设置server.servlet.context-path
针对于 ContextPath 的问题,最简单的便是直接变更应用的 server.servlet.context-path
, 配置如下
1 | # application.yaml |
这样以上两个问题就能够被解决,但该方案也有自己的问题:
- 一个应用只能指定一个 ContextPath,若存在多个不同子路径的反向代理,该方法就无法正常运转
- 应用已经在内网被其他服务引用了,但又需要代理到外网的子路径给其他外部服务使用,且内网应用无法修改引用的地址(比如维护人员已经全部离场)
设置server.forward-headers-strategy
1 | # application.yaml |
1 | # nginx |
通过设置在 spring boot 的配置文件中将server.forward-headers-strategy
设置为framework
,并且在 nginx 设置X-Forwarded-Prefix
为与 location 一致,每个请求执行时应用的 ContextPath 将与X-Forwarded-Prefix
一致