在Play框架1中,您可以在routes文件中使用类似的内容(查看http://www.playframework.org/documentation/1.2.5/routes#syntax处的文档)
GET /clients/? Clients.index
这样路由将匹配/ api / clients以及/ api / clients /
如何在Play框架2中实现相同的目标?
答案 0 :(得分:70)
从SEO的角度来看,与trailing slash
相同的链接是没有它的链接。强烈建议始终使用一个模式(牵引或非牵引链接)。
虽然有不同的学校哪一个更好,但最重要的是将301从“错误”的URL重定向到正确的。使用“Dynamic part spanning several /”可以轻松实现游戏。
我个人更喜欢非拖尾版本,也许是因为在Play中实现它就像写几条简单的线条一样。添加到您的路线文件这个规则,在开头的某个地方(保留斜线 - 这很重要,因为它不被视为生成组中的下一个斜杠,并且允许轻松匹配牵引的URL):
GET /*path/ controllers.Application.untrail(path: String)
然后你可以在控制器中进行重定向 - 到param,所以最后没有斜线:
Java
public static Result untrail(String path) {
return movedPermanently("/" + path);
}
Scala
def untrail(path: String) = Action {
MovedPermanently("/" + path)
}
到目前为止,所有以斜杠结尾的路线都将重定向到非追踪版本。容易:)
当然,强烈建议使用反向路由器生成正确的URL - 以最小化冗余重定向。此外,如果您在某处(即在某些JS或外部应用程序中)对URL进行硬编码,那么最好还是编写正确的URL,而不是每次都进行转换。如果您计划发布一些公共API在文档中做一个注释,您的应用程序更喜欢哪种模式,那么开发人员将收到警告,并且(可能)将准备正确的调用。
更重要的是 - 它对于GET
路线最为重要,因为它们是客户端的操纵对象。在使用POST
,PUT
,DELETE
和其他人时,您不需要(或者更确切地说,您不应该)关注重定向,因为用户无法更改重定向那样你需要记住你选择哪种方式。如果是错误的电话,即。对于POST,只返回404错误 - 因此第3部分应用程序的开发人员将有义务使用正确的结尾。
答案 1 :(得分:7)
我已经设法提出了一些东西,它并不像我希望的那么简单,但它也不是火箭科学
import play.api.mvc.RequestHeader
import play.api.Play.current
class NormalizedRequest(request: RequestHeader) extends RequestHeader {
val headers = request.headers
val queryString = request.queryString
val remoteAddress = request.remoteAddress
val method = request.method
val path = request.path.stripSuffix("/")
val uri = path + {
if(request.rawQueryString == "") ""
else "?" + request.rawQueryString
}
}
object NormalizedRequest {
def apply(request: RequestHeader) = new NormalizedRequest(request)
}
然后我在Global.scala
中使用它override def onRouteRequest(request: RequestHeader): Option[Handler] = {
super.onRouteRequest(NormalizedRequest(request))
}
答案 2 :(得分:5)
更新了@opensas和@lloydmeta的例子,用于播放2.5
/**
* HttpRequestHandler that removes trailing slashes from requests.
*/
class TrailingSlashNormaliserHttpRequestHandler(router: Router, errorHandler: HttpErrorHandler, configuration: HttpConfiguration, filters: HttpFilters) extends HttpRequestHandler {
private val default = new DefaultHttpRequestHandler(router, errorHandler, configuration, filters)
override def handlerForRequest(request: RequestHeader): (RequestHeader, Handler) = {
default.handlerForRequest(removeTrailingSlash(request))
}
private def removeTrailingSlash(origReq: RequestHeader): RequestHeader = {
if (origReq.path.endsWith("/") && origReq.path != "/") {
val path = origReq.path.stripSuffix("/")
if (origReq.rawQueryString.isEmpty) {
origReq.copy(path = path, uri = path)
}else {
origReq.copy(path = path, uri = path + s"?${origReq.rawQueryString}")
}
} else {
origReq
}
}
}
有关如何应用处理程序的说明,请参阅https://www.playframework.com/documentation/2.5.x/ScalaHttpRequestHandlers
答案 3 :(得分:1)
这是基于opensas's answer,只是简化了一点,以便在copy
上重复播放Play的内置RequestHeader
方法,以便原始{{1}中的所有内容保存,如id,标签,版本,安全等。
RequestHeader
答案 4 :(得分:1)
此处针对 Play 2.8 的其他答案的更新:
play.http.requestHandler = your.package.here.TrailingSlashHandler
然后只需将其放入您的 conf 中即可注册:{{1}}
答案 5 :(得分:0)
在路径文件中添加两次条目。一个有斜线,一个没有。