Can I capture the following two routes in a single line?
GET /game controllers.Main.app.gamelist
GET /game/ controllers.Main.app.gamelist
This is currently not supported and a ticket has been submitted to the issue tracker. There is also a discussion regarding this (including some workarounds) on Google Groups.
Hopefully this will be implemented in some smart way soon.
If you are using playframework 1.x then it is:
GET /game/? controllers.Main.app.gamelist
Whilst this doesn't seem to be supported at the moment, it can be achieved by overriding onRouteRequest in Global.scala
We're doing it like this:
import play.api._
import play.api.mvc.{Handler, RequestHeader, Action, Controller}
object TrailingSlashRedirector extends Controller {
def redirect(request: RequestHeader) = Action {
Redirect(request.path.dropRight(1), request.queryString, 301)
}
}
object Global extends GlobalSettings {
override def onRouteRequest(request: RequestHeader): Option[Handler] = {
val EndsWithASlash= """/(.*)/$""".r
request.path match {
case EndsWithASlash(_) => Some(TrailingSlashRedirector.redirect(request))
case _ => super.onRouteRequest(request)
}
}
}
(Might be late for Jacob, but someone might find this useful)
I had this problem as well, here's my workaround:
I put at the END of my routes the following line (this way, it matches urls that didn't match anything else)
GET /*path controllers.Application.appendSlash(path: String)
And here's my Application.appendSlash:
public static Result appendSlash(String path) {
char ending = path.charAt(path.length() -1 );
if (ending != '/')
return redirect('/' + path + '/');
else
return notFound();
}
You may want to add your 404 Not Found view as a paramer to notFound()
Hope this helps
Davide
EDIT: Just one thing: this will work for common browser navigation (if someone types the url but forgets the trailing '/'), but it will NOT work with ajax or otherways automated requests: for that you will anyway have to type the complete url.
Another possibility is to put this into your Global-Object:
If a route with a trailing slash is not found it tries one with the trailing slash removed.
The routes file just has route without trailing slashes...
@Override
public Result onHandlerNotFound(Http.RequestHeader requestHeader) {
if (hasTrailingSlash(requestHeader.path())) {
return Action.redirect(removeLastChar(requestHeader.path()));
}
return super.onHandlerNotFound(requestHeader);
}
private static String removeLastChar(String value) {
return value.substring(0, value.length() - 1);
}
private static boolean hasTrailingSlash(String value) {
return value != null && value.endsWith("/");
}
Here's the solution I've found
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)
}
ans then I use it like this in Global.scala
override def onRouteRequest(request: RequestHeader): Option[Handler] = {
super.onRouteRequest(NormalizedRequest(request))
}
And here's a similar question: play framework2: remove trailing slash from urls