文件

§自訂路由

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,它定義了抽象方法 bindunbind

對於像

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。有問題或建議要分享嗎?前往 我們的社群論壇 與社群開始對話。