控制器概述
这是一个控制器:
package controllers;
import models.Client;
import play.mvc.Controller;
public class Clients extends Controller {
public static void show(Long id) {
Client client = Client.findById(id);
render(client);
}
public static void delete(Long id) {
Client client = Client.findById(id);
client.delete();
}
}
控制器里每个 公共的、静态的方法都被称为 action。一个action的格式总是:
public static void action_name(params...);
你可以在方法签名中定义参数。这些参数将会自动从相应的http参数里解析。
通常,一个action方法不包括一条返回语句。方法的退出是通过调用一个result方法。在这个例子中,render(…)就是一个result方法(执行并且展示一个模板)。
取回http参数
一个HTTP请求包括了很多数据。这些数据来源于:
URI 路径:in /clients/1541,1514是URI的动态部分
查询语句:/clients?id=1541.
请求体:如果请求来源于Http 表单,请求体包含了用x-www-urlform- 编码的表单数据
在所有的情况下,PLay提取这些数据并且建立一个包含所有http参数的映射 Map
使用参数映射
params 这个对象可以在任何controller中获取到(因为它是在父类controller中定义的)。这个对象包含了所有当前请求的http参数.
例如:
public static void show() {
String id = params.get("id");
String[] names = params.getAll("names");
}
你也可以叫play帮你做类型转换:
public static void show() {
Long id = params.get("id", Long.class);
}
但是等等,还有更好的方法呢。
从方法的签名
你可以直接从方法的签名中获取到http参数。java参数的名字必须要和http参数的名字一致才行。
例如:
/clients?id=1451
一个action方法 能获取到id的值通过在签名中声明id这个参数。
public static void show(String id) {
System.out.println(id);
}
你也可以用其他的java类型而不仅仅是string。在这种情况下,play框架将会尽力将参数值转换为正确的java类型.
public static void show(Long id) {
System.out.println(id);
}
如果参数有很多个值,你可以声明一个array的参数。
public static void show(Long[] id) {
for(String anId : id) {
System.out.println(anid);
}
}
或者是集合类型:
public static void show(List<Long> id) {
for(String anId : id) {
System.out.println(anid);
}
}
http到java绑定的高级用法
简单类型
日期 date
使用’@As ‘注解,可以指定日期格式。
archives?from=21/12/1980
public static void articlesSince(@As("dd/MM/yyyy") Date from) {
List<Article> articles = Article.findBy("date >= ?", from);
render(articles);
}
Calendar
文件 File
Arrays or collections
public static void show(Long[] id) {
…
}
或者:
public static void show(Set<Long> id) {
…
}
也可以指定为:
public static void show(Map<String, String> client) {
…
}
持久化对象的绑定 POJO object
public static void create(Client client ) {
client.save();
show(client);
}
JPA对象的绑定
user.id = 1
&user.name=morten
&user.address.id=34
&user.address.street=MyStreet
public static void save(User user) {
user.save(); // ok with 1.0.1
}
自定义绑定
@play.data.binding.As
public static void update(@As("dd/MM/yyyy") Date updatedAt) {
…
}
public static void update(
@As(
lang={"fr,de","en","*"},
value={"dd/MM/yyyy","dd-MM-yyyy","MM-dd-yy"}
)
Date updatedAt
) {
…
}
public static void update(@As(",") List<String> items) {
…
}
@play.data.binding.NoBinding
这个注解允许你不绑定某个字段,解决潜在的安全问题。
public class User extends Model {
@NoBinding("profile") public boolean isAdmin;
@As("dd, MM yyyy") Date birthDate;
public String name;
}
public static void editProfile(@As("profile") User user) {
…
}
在这种情况下,isAdmin 字段永远不会被绑定在editProfile 这个action上。
play.data.binding.TypeBinder / TypeUnbinder
@As这个注解也允许你定义一个完全自我控制的绑定器/no.通过实现TypeBinder / TypeUnbinder接口。
public class MyCustomStringBinder implements TypeBinder<String>, TypeUnbinder<String> {
public Object bind(String name, Annotation[] anns, String value,
Class clazz) {
return "!!" + value + "!!";
}
@Override
public void unBind(Map<String, Object> result, Object src, Class<?> srcClazz,
String name, Annotation[] annotations) throws Exception {
String value = (String) src;
if(value != null){
value = value.replaceAll("^!!", "").replaceAll("!!$", "");
}
result.put(name, value);
}
}
之后,在action里使用:
public static void anyAction(@As(binder=MyCustomStringBinder.class)
String name) {
…
}