This chapter introduces several ways to define generic action functionality.
这章节介绍几个定义通用action功能的方式。
Previously, we said that an action is a Java method that returns aplay.mvc.Result
value. Actually, Play manages internally actions as functions. Because Java doesn’t support first class functions, an action provided by the Java API is an instance of play.mvc.Action
:
前面我们说过,一个action就是一个返回play.mvc.Result
值的java方法。实际上,Play在内部吧action当作函数。这是因为java不支持一级函数,一个java API 提供的action是一个play.mvc.Action
实例:
public abstract class Action { public abstract Result call(Http.Context ctx); }
Play builds a root action for you that just calls the proper action method. This allows for more complicated action composition.
Play会构建根action,它仅仅用来调用恰当的action方法,这允许更复杂的action组合。
You can compose the code provided by the action method with anotherplay.mvc.Action
, using the @With
annotation:
你可以使用 @With
注解组合action方法
@With(VerboseAction.class)
public static Result index() {
return ok("It works!");
}
Here is the definition of the VerboseAction
:
这是 VerboseAction
的定义:
public class VerboseAction extends Action.Simple {
public Result call(Http.Context ctx) throws Throwable {
Logger.info("Calling action for " + ctx); return delegate.call(ctx);
}
}
At one point you need to delegate to the wrapped action using delegate.call(...)
.
有时你需要用 delegate.call(...)
调用被包裹的action。
You also mix with several actions:
你也可以把几个action混在一起使用:
@With(Authenticated.class, Cached.class)
public static Result index() {
return ok("It works!");
}
Note:
play.mvc.Security.Authenticated
andplay.cache.Cached
annotations and the corresponding predefined Actions are shipped with Play. See the relevant API documentation for more information.注意:
play.mvc.Security.Authenticated
和play.cache.Cached
注解以及相应Action在Play中已经预定义了。详情请看相关API文档。
You can also mark action composition with your own annotation, which must itself be annotated using @With
:
你可以用自定义的注解来标记action组合,但它必须被 @With
注释。
@With(VerboseAction.class)
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Verbose {
boolean value() default true;
}
You can then use your new annotation with an action method:
你可以对action方法使用新的注解:
@Verbose(false)
public static Result index() {
return ok("It works!");
}
Your Action
definition retrieves the annotation as configuration:
你的 Action
定义会象configuration那样获得注解:
public class VerboseAction extends Action<Verbose> {
public Result call(Http.Context ctx) {
if(configuration.value) {
Logger.info("Calling action for " + ctx);
}
return delegate.call(ctx);
}
}
You can also put any action composition annotation directly on the Controller
class. In this case it will be applied to all action methods defined by this controller.
你也可以直接在 Controller
上使用注解,这样会对这个控制器的所有action方法起作用。
@Authenticated
public Admin extends Controller {
…
}