Introduction to Java microframeworks

Jump into Java microframeworks, Part 4: Play

A closer look at Java's original, ultra-lightweight web development stack

1 2 Page 2
Page 2 of 2

Next return to index.html.scala and make the form look like what you see in Listing 15. We're adding a couple of IDs to elements in the form, which our hello.js script will use. In Listing 15, we attach an onClick handler to #addGroupButton, then use #groupForm to get the data from the form. Notice that we also remove the action for the form, since we don't need it anymore.

Listing 15. Updated Create Group form


<form method="post" id="groupForm">
	<input type="text" name="name"></input>
	<button id="addGroupButton">Create Group</button>
</form>

Now when a user clicks Add Group, the application will POST/submit a JSON object with the form data to /group. The JSON will look something like: {"name": "The Police"}.

Update the route

Next we'll change the route for /group POST. The script in Listing 16 (the route file) should replace the old /group mapping.

Listing 16. Route file update for create group with JSON


POST    /group						controllers.Application.createGroupJSON()

Finally, we'll create the new createGroupJSON() method, as in Listing 17.

Listing Listing 17. createGroupJSON() method


 public Result createGroupJSON() {
    	Group group = Form.form(Group.class).bindFromRequest().get();
    	group.save();
    	return ok("{\"message\":\"Added a Group!\"}");
    }

Notice that Play is smart enough that we can still use the Form.form(Group.class).bindFromRequest() handler to get our Group instance from the JSON request body. We can call save() on the instance just as we did before. This will be followed by returning a status 200 with the ok() call, sending a simple JSON response body with a message field.

Queries in Play

So, we can create groups and save them to the database -- success! Now let's see how we could render out the existing groups. We'll start by adding a route, as shown in Listing 18.

Listing Listing 18. loadGroups route


GET    /groups						controllers.Application.loadGroups()

Our loadGroups handler shows how you can utilize the EBean query API:

Listing Listing 19. EBean query API in loadGroups()

.
import com.avaje.ebean.Ebean;
import play.libs.Json;
//...
public Result loadGroups() {
    	List<Group> groups = Ebean.find(models.Group.class).findList();
    	return ok(Json.toJson(groups).toString());
    }

In Listing 19, Ebean exposes a simple find method for querying entities by class type. We can then take the List and convert it to JSON, with Play's built-in JSON library. If you hit http://localhost:9000/groups with a GET request, you'll now see a JSON-formatted list of the existing groups. Before we move on, let's explore another way to handle querying in Play.

Another query pattern

Adding a static Finder member to the Group class is a common querying pattern in Play, as shown in Listing 20.

Listing Listing 20. static Finder member on Group class


public static Finder<String, Group> find = new Finder<String, Group>(Group.class);

Returning to the loadGroups() method on the application controller, we would change it to look like Listing 21.

Listing Listing 21. Application.loadGroups()


public Result loadGroups() {
    	//List<Group> groups = Ebean.find(models.Group.class).findList();
    	List<Group> groups = Group.find.all();
    	return ok(Json.toJson(groups).toString());
    }

Now we are set up to use the static Finder to access the list of groups.

Complete the user interface

It's now a fairly simple exercise to render the groups to the UI. First, add a div to the index.html.scala page, like so: <div id="groups"></div>. Next. make the additions from Listing 22 to your hello.js.

Listing Listing 22. loadGroups additions to hello.js


App = {
		startup: function(){
			$("#addGroupButton").click(App.addGroup);
			App.loadGroups();
		},
		loadGroups: function(){
			$.getJSON( "/groups", function( data ) {
				  var items = [];
				  $.each( data, function( key, val ) {
				    items.push( "<li id='" + key + "'>" + val.name + "</li>" );
				  });
				 
				  $("#groups").empty();
				  $("#groups").html("<ul>"+items.join("")+"</ul>");
				});
		}
}

When the index page is first opened, the loadGroups method will execute, and some basic jQuery will generate an HTML list. That list will display the results of the JSON-formatted data from the GET /groups service. Whenever a group is added, the list will be refreshed to reflect the changes.

Nothing can stop us now -- we can save and list everything from ABBA to Zappa!

Conclusion

Between the setup in Part 1 and the simple programming exercise in this article, you should have a pretty good grasp of incorporating persistence, assets, views, and JSON in your Play-based applications. Play offers a lot of built-in functionality, and this tour gave us a sense of how things work in the Play idiom. Overall, Play is the most intensive of the Java microframeworks to get into, offering a full-stack alternative to standard Java tooling.

The learning curve is steeper with Play, but you get more integrated power at your beck and call -- just remember that adding EBean was a matter of turning on a plugin. You'll find that other features have similar support, such as Play's security plugin.

Play is a no-brainer if you're a fan of Scala, and it's an overall solid Java framework. You just need to be willing to trade some of your standard Java mindset and tooling for a slightly different programming paradigm.

1 2 Page 2
Page 2 of 2