5

I have a create action in a Play! framework controller that should return the HTTP status code Created and redirect the client to the location of the created object.

public class SomeController extends Controller {

    public static void create() {
        Something something = new Something();
        something.save();
        response.status = StatusCode.CREATED;  // Doesn't work!
        show(something.id);
    }

    public static void show(long id) {
        render(Something.findById(id));
    }
}

See also method chaining in the Play! framework documentation.

The code above returns the status code 302 Found instead of 201 Created. What can I do to let Play return the correct status (and Location header)?

ndeverge
  • 20,808
  • 4
  • 54
  • 84
deamon
  • 78,414
  • 98
  • 279
  • 415

3 Answers3

6

The reason this is happening, is that once you created your something, you are then telling play to Show your something, through calling the show action.

To achieve this, play is performing a redirect (to maintain its RESTful state), to tell the browser that as a result of calling the create() action, it must now redirect to the show() action.

So, you have a couple of options.

  1. Don't render a response, and let the client side handle where it goes after creating it (not ideal).
  2. Instead of calling show(), simply render it yourself in the create() method...

To use option 2, it may look like the following:

public static void create() {
    Something something = new Something();
    something.save();
    response.status = StatusCode.CREATED;
    renderTemplate("Application/show.html", something);
}
o-0
  • 1,630
  • 12
  • 27
Codemwnci
  • 51,224
  • 10
  • 90
  • 127
  • 1
    `201 Created` should be send together with a `Location` header which would not happen with solution 2. Could you please explain solution 1, I don't understand it? – deamon Sep 18 '11 at 17:14
  • Solution 1 is not good. It is basically saying, after your request create, then request show(), so your flow is decided client side (i.e. javascript), rather than serverside in your action. – Codemwnci Sep 18 '11 at 17:30
  • 3
    I have checked the source code for Play (1.2.3) and the Redirect object, has a code, which is defaulted to 302. It has a constructor to offer a different code, but this constructor does not appear to be used in the framework. – Codemwnci Sep 18 '11 at 17:53
1

Example code for setting the status code in Play framework: Response.current().status = Http.StatusCode.CREATED;

Robert de W
  • 286
  • 6
  • 24
0

In the play framework, calling another action performs a redirect except that the action called is not public. So, here is one of the solutions:

public class SomeController extends Controller {

    public static void create() {
        Something something = new Something();
        something.save();
        response.status = StatusCode.CREATED;  // Doesn't work!
        show(something.id);
    }

    private static void show(long id) {
        render(Something.findById(id));
    }
}
clemens
  • 14,173
  • 11
  • 38
  • 52
Andy
  • 31
  • 1
  • 4