Play 2.6 路由
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.