routers
conf/routers文件中配置路由信息
一条路由信息包括两个部分:
- http方法(get、post等)
- 请求路径
无参路由
routers文件
GET /count controllers.CountController.count
代码
package controllers;
import play.mvc.Controller;
import play.mvc.Result;
import services.Counter;
import javax.inject.Inject;
import javax.inject.Singleton;
@Singleton
public class CountController extends Controller {
private final Counter counter;
@Inject
public CountController(Counter counter) {
this.counter = counter;
}
public Result count() {
return ok(Integer.toString(counter.nextCount()));
}
一般形式
GET /count/see/:i controllers.CountController.see(i:Int)
public Result see(int i){return ok(Integer.toString(i));}//参数形式使用scala的方式
# request example http://localhost:9000/count/see/2
为参数设置默认值
# http://localhost:9000/count/see?i=2
GET /count/see controllers.CountController.see(i:Int ?= 1 )
参数类型为String的情况下,可省略类型参数
GET /count/seeString/:s controllers.CountController.seeString(s)
可选参数
# The version parameter is optional. E.g. /api/list-all?version=3.0
GET /api/list-all controllers.Api.list(version ?= null)
# or
GET /api/list-all controllers.Api.listOpt(version: java.util.Optional[String])
一条请求可能会匹配到多条路由,默认使用第一条路由
反向路由
在routes文件中配置的controller,都会在routes
包下生成一个reverse controller
(在Play2.6.10中,这些类在target/scala/routes/main/controllers
目录下),这些controller拥有和原controller一样的方法及签名,但是返回一个play.mvc.Call
实例而不是play.mvc.Result
实例
在调用一个请求时,可以在代码中通过重定向的方式去生成新一个新的url,并调用该url
假设已有方法hello
及相应的映射
public Result hello(String name) {
return ok("Hello " + name + "!");
}
GET /hello/:name controllers.CountController.hello(name)
// Redirect to /hello/Bob
public Result index() {
return redirect(controllers.routes.CountController.hello("Bob"));
}
相对路由(Relative routes)
通过play.mcv.Call
返回的url都是以/
开头的绝对路由,在使用代理、负载均衡、API gateways的环境下可能会出现问题。
package controllers;
import play.*;
import play.mvc.*;
public class Relative extends Controller {
public Result helloview() {
ok(views.html.hello.render("Bob", request()));
}
public Result hello(String name) {
return ok("Hello " + name + "!");
}
}
routes
文件
GET /foo/bar/hello controllers.Relative.helloview
GET /hello/:name controllers.Relative.hello(name)
views/hello.scala.html
文件
@(name: String, request: Http.RequestHeader)
<h1>Hello @name</h1>
<a href="@routes.Relative.hello(name)">Absolute Link</a>
<a href="@routes.Relative.hello(name).relativeTo(request)">Relative Link</a>
调用/foo/bar/hello
产生的html文件
<h1>Hello Bob</h1>
<a href="/hello/Bob">Absolute Link</a>
<a href="../../hello/Bob">Relative Link</a>
从这里可以看的第二条url已经为相对路径
推荐使用相对路由的场景:
- Hosting an app behind a web gateway that prefixes all routes with something other than what is configured in your conf/routes file, and roots your application at a route it’s not expecting
- When dynamically rendering stylesheets, you need asset links to be relative because they may end up getting served from different URLs by a CDN.