Play框架静态资源路由问题:/assets与/assets/id无法识别
问题根源与解决方案
这个问题其实是Play框架路由的匹配顺序规则导致的,我来给你拆解清楚:
首先,Play的路由是按照你在路由文件里写的从上到下的顺序进行匹配的,只要找到第一个符合请求路径的路由,就会用它来处理请求,不会再往下找其他路由了。
你的情况里,GET /assets/*file这个静态资源路由写在了自定义的/assets/和/assets/id路由前面。这就导致:
- 当你请求
/assets时,虽然你有对应的自定义路由,但Play先匹配到了/assets/*file,然后Assets控制器会去/public目录下找对应的资源——显然不存在,所以返回404。 - 当你请求
/assets/id时,Play会把id当成静态资源的文件名,同样去/public里找这个文件,找不到就报错。
而当你移除/assets/*file路由后,Play就会匹配到你后面的自定义路由,自然就正常工作了。
解决办法
有两个简单的方案可以选:
方案一:调整路由顺序
把你的自定义/assets/、/assets/id路由放在静态资源路由的前面,让Play优先处理这些特定路径的请求。比如:
# 自定义路由先写 GET /assets/ mypackage.MyController.index GET /assets/id mypackage.MyController.show(id: Long) # 静态资源路由放在后面 GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset)
这样一来,特定的/assets和/assets/id请求会被你的自定义控制器处理,而像/assets/css/main.css这种真正的静态资源请求,才会走到Assets控制器。
方案二:修改静态资源的路由前缀
如果不想调整顺序,也可以把静态资源的路由前缀换掉,比如改成/static,这样就不会和你的/assets开头的自定义路由冲突了:
# 自定义路由保持不变 GET /assets/ mypackage.MyController.index GET /assets/id mypackage.MyController.show(id: Long) # 静态资源用新前缀 GET /static/*file controllers.Assets.versioned(path="/public", file: Asset)
之后访问静态资源就用/static/xxx的路径即可。
内容的提问来源于stack exchange,提问作者Julie
相关产品推荐
相关产品推荐

