Reputation: 576
We are currently working on Play 2.5.x
We wanted to achive case insensitive routing to be done. Say for example
GET /via/v1/organizations http.organizationApi()
In the URL we wanted to achive
http://localhost:9000/abc/v1/organizations
http://localhost:9000/ABC/V1/OrganIZations
Is the a way to achive this bu using regular expression? Can some one point to or provide me an example?
Upvotes: 3
Views: 1099
Reputation: 21
with play 2.8, answer above is not working. the play api has changed so I pasted my code here.
class CaseInsensitive @Inject()(router: Router, errorHandler: HttpErrorHandler, configuration: HttpConfiguration, filters: EssentialFilter*)
extends DefaultHttpRequestHandler(new DefaultWebCommands, None, router, errorHandler, configuration, filters){
override def routeRequest(request: RequestHeader): Option[Handler] = {
val target = request.target;
val newPath = target.path.toLowerCase
val newTarget = request.target.withPath(newPath)
val newRequest = request.withTarget(newTarget);
router.handlerFor(newRequest)
}
}
Upvotes: 0
Reputation: 12986
You can define a request handler to make the URL case insensitive. In this case, the following handler will just convert the url to lowercase, so in your routes the url should be defined in lowercase:
import javax.inject.Inject
import play.api.http._
import play.api.mvc.RequestHeader
import play.api.routing.Router
class MyReqHandler @Inject() (router: Router, errorHandler: HttpErrorHandler,
configuration: HttpConfiguration, filters: HttpFilters
) extends DefaultHttpRequestHandler(router, errorHandler, configuration, filters) {
override def routeRequest(request: RequestHeader) = {
val newpath = request.path.toLowerCase
val copyReq = request.copy(path = newpath)
router.handlerFor(copyReq)
}
}
And in application.conf
reference it using:
# This supposes MyReqHandler.scala is in your project app folder
# If it is in another place reference it using the correct package name
# ex: app/handlers/MyReqHandler.scala --> "handlers.MyReqHandler"
play.http.requestHandler = "MyReqHandler"
Now, if you have a route define to "/persons/create", whatever case combination will work (ex: "/PeRsOns/cREAtE")
There are two caveats though:
You can only use this with Scala actions. If your routes file references a Java controller method, you will get an odd exception:
[error] p.c.s.n.PlayRequestHandler - Exception caught in Netty
scala.MatchError: Right((play.core.routing.HandlerInvokerFactory$JavaActionInvokerFactory$$anon$14$$anon$3@22d56da6,play.api.DefaultApplication@67d7f798)) (of class scala.util.Right)
If this is your case you can find more info here
If your url have parameters, those will also be transformed. For example, if you have a route like this
GET /persons/:name/greet ctrl.Persons.greet(name: String)
a call to "/persons/JohnDoe/greet" will be transformed to "/persons/johndoe/greet", and your greet
method will receive "johndoe" instead of "JohnDoe" as parameter. Note that this does not apply to query string parameters.
Depending in your use case, this can be problematic.
Upvotes: 3