§自訂路由
Play 提供一種機制,可從路徑或查詢字串參數繫結類型。
§PathBindable
PathBindable 允許從 URL 路徑繫結商業物件;這表示我們將能夠定義路由,例如 /user/3
來呼叫下列動作
§controller
public Result user(User user) {
return ok(user.name);
}
user
參數將自動使用從 URL 路徑萃取的 ID 擷取,例如使用下列路由定義
§/conf/routes
GET /user/:user controllers.BinderApplication.user(user: javaguide.binder.models.User)
任何實作 PathBindable
的類型 T
都可以繫結至/從路徑參數。
它定義了抽象方法 bind
(從路徑建立值)和 unbind
(從值建立路徑片段)。
對於像
public class User implements PathBindable<User> {
public Long id;
public String name;
繫結 :id
路徑參數的繫結器使用的一個簡單範例
@Override
public User bind(String key, String id) {
// findById meant to be lightweight operation
User user = findById(Long.valueOf(id));
if (user == null) {
throw new IllegalArgumentException("User with id " + id + " not found");
}
return user;
}
@Override
public String unbind(String key) {
return String.valueOf(id);
}
在此範例中,會呼叫 findById
方法來擷取 User
執行個體。
注意:在實際應用中,此類方法應為輕量級,且不涉及例如資料庫存取,因為程式碼會在伺服器 IO 執行緒上呼叫,且必須完全非封鎖。因此,您會例如使用簡單的物件識別碼作為路徑可繫結,並使用動作組合來擷取實際值。
§QueryStringBindable
類似的機制用於查詢字串參數;可以定義像 /age
這樣的路由來呼叫動作,例如
§controller
public Result age(AgeRange ageRange) {
return ok(String.valueOf(ageRange.from));
}
會自動使用從查詢字串擷取的參數來擷取 age
參數,例如 /age?from=1&to=10
任何實作 QueryStringBindable
的類型 T
都可以繫結至/從一個或多個查詢字串參數。類似於 PathBindable
,它定義了抽象方法 bind
和 unbind
。
對於像
public class AgeRange implements QueryStringBindable<AgeRange> {
public Integer from;
public Integer to;
繫結 :from
和 :to
查詢字串參數的繫結器使用的一個簡單範例
@Override
public Optional<AgeRange> bind(String key, Map<String, String[]> data) {
try {
from = Integer.valueOf(data.get("from")[0]);
to = Integer.valueOf(data.get("to")[0]);
return Optional.of(this);
} catch (Exception e) { // no parameter match return None
return Optional.empty();
}
}
@Override
public String unbind(String key) {
return new StringBuilder().append("from=").append(from).append("&to=").append(to).toString();
}
Play 提供的所有繫結器都會在它們的 unbind
方法中自動套用表單 URL 編碼,因此所有特殊字元都會安全地經過 URL 編碼。然而,在實作自訂繫結器時不會自動發生這種情況,因此請務必在必要時對金鑰/值部分進行編碼
@Override
public String unbind(String key) {
String identifierEncoded;
try {
identifierEncoded = URLEncoder.encode(identifier, "utf-8");
} catch (Exception e) {
// Should never happen
identifierEncoded = identifier;
}
return new StringBuilder()
// Key string doesn't contain special characters and doesn't need form URL encoding:
.append("identifier")
.append('=')
// Value string may contain special characters, do encode:
.append(identifierEncoded)
.toString();
}
下一步:擴充 Play
在這個文件裡發現錯誤嗎?這個頁面的原始碼可以在 這裡 找到。在閱讀 文件指南 後,請隨時提交一個 pull request。有問題或建議要分享嗎?前往 我們的社群論壇 與社群開始對話。