You are viewing the documentation for the 2.3.x release series. The latest stable release series is 3.0.x.

§Action composition

This chapter introduces several ways to define generic action functionality.

§Reminder about actions

Previously, we said that an action is a Java method that returns a play.mvc.Result value. Actually, Play manages internally actions as functions. Because Java doesn’t yet support first class functions, an action provided by the Java API is an instance of play.mvc.Action:

public abstract class Action {
  public abstract Promise<Result> call(Context ctx) throws Throwable;

Play builds a root action for you that just calls the proper action method. This allows for more complicated action composition.

§Composing actions

Here is the definition of the VerboseAction:

public class VerboseAction extends play.mvc.Action.Simple {
    public F.Promise<Result> call(Http.Context ctx) throws Throwable {"Calling action for " + ctx);

You can compose the code provided by the action method with another play.mvc.Action, using the @With annotation:

public static Result verboseIndex() {
    return ok("It works!");

At one point you need to delegate to the wrapped action using

You also mix several actions by using custom action annotations:

@Cached(key = "index.result")
public static Result authenticatedCachedIndex() {
    return ok("It works!");

Note: play.mvc.Security.Authenticated and play.cache.Cached annotations and the corresponding predefined Actions are shipped with Play. See the relevant API documentation for more information.

§Defining custom action annotations

You can also mark action composition with your own annotation, which must itself be annotated using @With:

@Target({ElementType.TYPE, ElementType.METHOD})
public @interface VerboseAnnotation {
    boolean value() default true;

Your Action definition retrieves the annotation as configuration:

public class VerboseAnnotationAction extends Action<VerboseAnnotation> {
    public F.Promise<Result> call(Http.Context ctx) throws Throwable {
        if (configuration.value()) {
  "Calling action for " + ctx);

You can then use your new annotation with an action method:

public static Result verboseAnnotationIndex() {
    return ok("It works!");

§Annotating controllers

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.

public Admin extends Controller {

§Passing objects from action to controller

You can pass an object from an action to a controller by utilizing the context args map.

public class PassArgAction extends play.mvc.Action.Simple {
    public F.Promise<Result> call(Http.Context ctx) throws Throwable {
        ctx.args.put("user", User.findById(1234));

Then in an action you can get the arg like this:

public static Result passArgIndex() {
    Object user = ctx().args.get("user");
    return ok(Json.toJson(user));

Next: Content negotiation

Found an error in this documentation? The source code for this page can be found here. After reading the documentation guidelines, please feel free to contribute a pull request. Have questions or advice to share? Go to our community forums to start a conversation with the community.