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