Enterprise Java

Play! Framework tutorial for beginners

Play is a Web Framework for Scala and Java and it is a really powerful and complete one. It provides an easy way of building web servers, running on an embedded jetty, and even rest clients with its WS library.

In this example, we are going to get a Play Application running. We’ll see how to create it from scratch using typesafe activator 1.2.12, sbt 0.13.5, java 1.8.0_66, scala 2.11.6 and Play 2.4.3. We’ll learn how to create Actions, how does routing work in play and we’ll see its very powerful template engine in action.

We are using activator because it makes it easier to start a project from scratch. It provides a few project templates, including play with scala, play with java, akka and mongodb, among others.

1. Creating the Project

So we run:

$> activator new

And we’ll see something like:

	Fetching the latest list of templates...

	Choose from these featured templates or enter a template name:
		1) minimal-akka-java-seed
		2) minimal-akka-scala-seed
		3) minimal-java
		4) minimal-scala
		5) play-java
		6) play-scala
	(hit tab to see a list of all templates)

For now we’ll choose 6) play-scala for scala or 5) play-java for java, as you wish.

It will ask for the name of your application, play-example will work for us now, so we type it and hit enter.

After a little while we’ll see it’s done and we can cd play-example && ll to see what it did:

	total 1228
	drwxr-xr-x 7 svinci svinci 4096 nov 2 12:22 .
	drwxr-xr-x 3 svinci svinci 4096 nov 2 12:22 ..
	-rwxr--r-- 1 svinci svinci 9507 nov 2 12:22 activator
	-rwxr--r-- 1 svinci svinci 7110 nov 2 12:22 activator.bat
	-rw-r--r-- 1 svinci svinci 1188338 nov 2 12:22 activator-launch-1.2.12.jar
	drwxr-xr-x 4 svinci svinci 4096 nov 2 12:22 app
	-rw-r--r-- 1 svinci svinci 481 nov 2 12:22 build.sbt
	drwxr-xr-x 2 svinci svinci 4096 nov 2 12:22 conf
	-rw-r--r-- 1 svinci svinci 80 nov 2 12:22 .gitignore
	-rw-r--r-- 1 svinci svinci 591 nov 2 12:22 LICENSE
	drwxr-xr-x 2 svinci svinci 4096 nov 2 12:22 project
	drwxr-xr-x 5 svinci svinci 4096 nov 2 12:22 public
	-rw-r--r-- 1 svinci svinci 148 nov 2 12:22 README
	drwxr-xr-x 2 svinci svinci 4096 nov 2 12:22 test

This output should be the same for both languages. As you can see, it created two binaries (activator and activator.bat) and a jar, these are created by activator, so if you want to contribute to this application from a computer which hasn’t activator installed, yo can do it anyway, but we will just delete them.

It also created a few directories: app, conf, project, public and test, which we’ll explain one by one soon enough.

There is also a build.sbt, which holds the build definition for sbt.

2. Directory Structure

2.1. The server side source directory: app

This directory holds all the server side source code and play templates. As we can see, activator created, inside of this directory, two packages: controllers and views.

In the controllers directory, there is already an Application, which is an example controller generated by activator. Let’s take a look to both java and scala examples:


	package controllers;
	import play.*;
	import play.mvc.*;
	import views.html.*;
	public class Application extends Controller {
	    public Result index() {
	         return ok(index.render("Your new application is ready."));


	package controllers
	import play.api._
	import play.api.mvc._
	class Application extends Controller {
	  def index = Action {
	    Ok(views.html.index("Your new application is ready."))

In play, the handler of an HTTP request is called an Action, which holds a method that receives a request and returns a result, and this class defines one called index, which returns Ok with some HTML generated by play’s template engine. It is calling a template called index, located in views.html, with a String as parameter, so we get back and go to the views package and hit ll. We’ll see:

	total 16
	drwxr-xr-x 2 svinci svinci 4096 nov  2 12:22 .
	drwxr-xr-x 4 svinci svinci 4096 nov  2 12:22 ..
	-rw-r--r-- 1 svinci svinci   80 nov  2 12:22 index.scala.html
	-rw-r--r-- 1 svinci svinci  481 nov  2 12:22 main.scala.html

As you can see, there is no html package here, that’s because, on compilation, play creates that package with these templates compiled as scala classes. That means you can write scala code inside these templates. Let’s check out index.scala.html for it is the one being called from our index action.


	@(message: String)
	@main("Welcome to Play") {

Play templates are written in scala, but this should not be a problem for java developers, as you should never write complex logic in templates. Most of the time you will just access data from your model objects.

The first line defines the constructor, as @(parameter1Name: Parameter1Type, ..., parameterNName: ParameterNType), receiving a String, which is consistent with what we saw in our index action.

The second line is making a call to main template, which is in the same package, and passes a string as a parameter. But also, there is some code between the curly braces. The curly braces, in that context, define a piece of HTML to be returned. Inside them, @play20.welcome is being called, which is a play function that returns a welcome page with some message, given as a parameter, as heading.

So, let’s take a look at that main template.


	@(title: String)(content: Html)
	<!DOCTYPE html>
	<html lang="en">
		<link rel="stylesheet" media="screen" href="@routes.Assets.versioned("stylesheets/main.css")">
		<link rel="shortcut icon" type="image/png" href="@routes.Assets.versioned("images/favicon.png")">
		<script src="@routes.Assets.versioned("javascripts/hello.js")" type="text/javascript"></script>

Here, we see a constructor that defines two parameters: title and content. We are already familiar with values of type String, so just check out the title tag. Inside you see @title, and that’s how you render a value in a template. Also, inside the body tag, this template is rendering content. Strings, Ints, Booleans and Html are rendered almost seamlessly in play templates.

Also, check out the header for those links and the script. It’s using @routes.Assets.versioned to get those sources. I’ll get back to it later.

So here it is, a full HTML that’s going to be rendered when an HTTP request is done to our index action. So, where does that routing thingy happen?

2.2. The configuration directory: conf

From now on, it doesn’t matter if you are working with java or scala. Everything from here is common to all play applications.

Now we switch to that conf directory and ll.

total 20
drwxr-xr-x 2 svinci svinci 4096 nov  2 12:22 .
drwxr-xr-x 8 svinci svinci 4096 nov  2 14:42 ..
-rw-r--r-- 1 svinci svinci 1382 nov  2 12:22 application.conf
-rw-r--r-- 1 svinci svinci  637 nov  2 12:22 logback.xml
-rw-r--r-- 1 svinci svinci  335 nov  2 12:22 routes

The activator created an application.conf, which holds general configuration properties (db connections, service endpoints, etc.), logback.xml, logback’s logging configuration, and routes, and there are our endpoints defined. Check it out.


	# Routes
	# This file defines all application routes (Higher priority routes first)
	# ~~~~

	# Home page
	GET     /                           controllers.Application.index

	# Map static resources from the /public folder to the /assets URL path
	GET     /assets/*file               controllers.Assets.versioned(path="/public", file: Asset)

We need to see it as a three columns table, where the first one represents the http action (GET, POST, PUT, DELETE, HEAD, OPTIONS), the second one represents the path and the third one represents our bound action.

The first defined route is our index. You can read it like: All GET requests to / are handled by controllers.Application.index.

The second route lets us get back to that @routes.Assets.versioned in our main template. It is mapping all GET requests to /assets/* to controllers.Assets.versioned. Which receives a path, hardcoded with the value "/public" (this parameter is telling play where is the static content located in our project), and an Asset, which is a route to a file given as parameter in the url.

2.3. The static content directory: public

If you switch to this directory, you’ll see three other ones: images, javascripts and stylesheets. And as we’ve seen in our routes file, controllers.Assets.versioned is configured to serve static content from here. Inside these folders you will find some basic examples. A javascript file, a css file and an image (favicon).

So, what’s happening in our templates when we invoke @routes.Assets.versioned? In play this is called reverse routing. In the routes package, you will find references to every controller in your project, which hold URL builders of every defined action. So when you call @routes.Assets.versioned with the path to a file relative to "/public", it will render the absolute URL to that file. And this works for every action, parametrized or not.

2.4.The project directory: project

This directory should hold only sbt configuration files, such as build.properties, which defines sbt’s version, and plugins.sbt, which imports needed plugins.

Play has its own sbt plugin, com.typesafe.play:sbt-plugin, which is necessary for every play application, as a lot of play’s magic happens on compilation. It defines and overrides a lot of goals, such as run, clean and compile.

3. Running the application

Change to project’s root directory and run:

$> activator run

After it’s done resolving its dependencies and compiling the project you will see something like:

[info] p.c.s.NettyServer - Listening for HTTP on /0:0:0:0:0:0:0:0:9000

And when that’s printed out, your server is up and running. By default, it will be listening at http://localhost:9000/, check it out and you should see something like:

Play Scala App

4. Download the Code Project

This was a tutorial on the basics of play framework.

You can download the full source code of this example here: play-scala-example, play-java-example

Sebastian Vinci

Sebastian is a full stack programmer, who has strong experience in Java and Scala enterprise web applications. He is currently studying Computers Science in UBA (University of Buenos Aires) and working a full time job at a .com company as a Semi-Senior developer, involving architectural design, implementation and monitoring. He also worked in automating processes (such as data base backups, building, deploying and monitoring applications).
Notify of

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Inline Feedbacks
View all comments
Back to top button