Play Framework: Controller Development

In my previous post, I explained my experience using the EBean API to create Play models. With all the bugs sorted out with the models, I had hoped the controller development would be a breeze as there is not as much byte code manipulation as with the models. It definitely was not as frustrating, but writing and testing the controller takes a bit of knowledge of the framework’s static fields and methods.

Because each model would be access through a REST URI scheme, it was easy to define the routes and the necessary code. Honestly, most of the code was just duplicated to the point that I wonder if an abstract controller could be written to handle all the requests where we write a bit of custom code to augment object retrieval and storage. For instance, depending on the assumptions of an offer model, a method could be written to find a book in the database by ISBN or create a new Book object. In any case, once I had finished the warehouse controller and fixed up my textbook exchange objects, I found that creating controllers a relatively straight forward task.

Returning an Object Information
When I was writing my unit tests for the Warehouse application, I had a problem with returning field information other than the primary key. I had missed this key detail that is mentioned at Walkthrough of Play controller code @ 7:25.

Here is an example of the code:

public RequestModel extends Model {
  
  // other fields, constructor, and methods ...

  private String requestId;
  private Student student;

  public String toString() {
    return String.format("[Request %s ]", this.requestId, this.student);
  }
}
public RequestController extends Controller {

  // other routes ...

  public static Result newRequest() {
    Form<RequestModel> form = form(RequestModel.class).bindFromRequest();

    // continue form processing
  }
}

Defining the routes
Defining a REST route was pretty straight forward as the route pattern was unambiguous. There was an action, URI, and the related Java handler method. I wish it was this easy in the HttpServlet API. (I’m looking at you JSP)

Reverse Routes Not Found in Java
For the warehouse application, I first created the the Product model routes to familiarize myself with creating and testing a route. I had some difficulty referencing the reverse route in the Java test class, so I ran the Eclipse command to regenerate the class references:

play eclipse

@Test Annotation Ignored?
When I first ran my Product route test inside my ControllerTest.java file, the tests correctly returned the state of the tests. Once I had renamed the ControllerTest.java to TestController.java, the test results showed that only my model test had been run. In the background the tests are being run, because a call to System.out.println(“”) in side my ControllerTest tests will print to the console. The machine that I found this error on was running Windows 7 Home Premium 32bit, JDK 1.7.0_11, and Play 2.1.0. I have not experience this error on a laptop running Windows 8 Pro 64bit, JDK 1.7.0_11, and Play 2.1.0.

This bug seems to be a logger issue as the tests will correctly identify a change on my ControllerTest class and the tests will reappear if I rename the ControllerTest class.

After Thoughts
Although the Play Framework seems to take a lot less code in order to route up a web application, convention is a huge stumbling block to this framework. Why are methods such as status(request) or contentAsString(request) static methods rather than methods on the request object? Since Objects are one of Java’s strength, it is a bit confusing that those previous methods are offered as static. I bet that over time methods or fields such as the contentAsString will become second nature, so I am not that concerned about this idiosyncrasy.