文档

§自定义路由

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


发现此文档中的错误?此页面的源代码可以在此处找到。阅读完文档指南后,请随时贡献拉取请求。有疑问或建议要分享?前往我们的社区论坛与社区交流。