Skip to content

Routes and Controllers

pramode edited this page Jun 24, 2011 · 12 revisions

All about URL Routing

Basic stuff

Add a line to conf/routes:

GET /test Application.test

Now, write a function "test" and save it in app/controllers/Application.java

 public class Application extends Controller {

   public static void index() {
     render();
   }   

   public static void test() {

     render();   
   }   

 }

Create an HTML file test.html in app/views/Application/test.html

The "render" function called from "test" (which is a member of class Application) will render the file app/views/Application/test.html.

Patterns in url's

The line:

GET /fun/{id1}/{id2} Application.fun

Will match the url:

/fun/abc/100

/fun/234a/dsd

.....

The part within {} represent variables.

The function "Application.fun" gets called with two parameters which will be equal to the actual value of the two variable parts of the url.

Here is the function:

  public static void fun(String id1, String id2) {
    System.out.println("id1="+id1+":id2="+id2);
  }   

(Note: the println will print to stdout. A blank screen is the browser output)

(Note: The parameters of "fun" have to be named as the corresponding variable parts of the routes file - in this case id1 and id2. If the names don't match, then the function parameters are set to default values like null for objects and 0 for int. The framework automatically performs type casting.)

Another way to get the HTTP parameters:

  public static void fun() {
    String a = params.get("id1");
    System.out.println("id1=" + a); 
  }   

The HTTP parameters can be accessed through the dictionary "params".

Another example:

route definition: GET /fun Application.fun

URL request: /fun/id1=10&id2=20

Method fun:

    public static void fun() {
       String a = params.get("id1");
       String b = params.get("id2");
       System.out.println("id1=" + a); 
       System.out.println("id2=" + b); 
    }   

More complex route handling

Create a model class, Client.java:

   package models;

   import java.util.*;
   import javax.persistence.*;

   import play.db.jpa.*;

   @Entity
   public class Client extends Model {

        public String name;
        public int age;


   }

Now, write the controller function:

   public static void fun(Client c){ 
      System.out.println("name=" + c.name);
      System.out.println("age=" + c.age);
   } 

This will respond to the URL:

GET /fun?c.name="pce"&c.age=35

(Note: database has to be configured for this example to work)

HTTP response

The "render" function renders a template and delivers the HTTP response. It never returns.

The "renderText" function renders a simple text message:

    public static void test() {

          renderText("Testing renderText....");   
    } 

Adding data to template scope:

Here is the controller function:

      public static void test() {
          Client client =  new Client();
          client.name = "Arun";
          renderArgs.put("client", client);
          render();
      }   

The class "Client" is defined in the file app/models/Client.java

Here is the template file, test.html (under app/views/Application/test.html):

         <html>
         <head>
            <title>Testing...</title>
         </head>

         <body>
         <h1>Testing....</h1>
         <p>
           Client name is ${client.name}

         </body>

         </html>

Instead of using renderArgs.put(), the easy way is to pass the variables to the render function:

      render(client)

The template will then be able to access properties of the object client using the ${...} notation. Multiple values can be passed in this way. (only local variables can be passed).

Redirection

The "redirect" method generates an HTTP redirect:

    redirect("http://www.google.com");

Action chaining

Read the documentation

Interceptors

Example:

     @Before
     static void dummyInterceptor() {
        System.out.println("interceptor called...");
     }

Functions annotated with @Before are "interceptors" - the function "dummyInterceptor" gets called before any action of this controller class is invoked. It can be used for making security checks (a simple example).

If you write:

  @Before(unless="fun")

this interceptor will get called before any action except "fun".

If you specify

  @Before(only={"fun", "test"})

the interceptor will be called only for the actions "fun" and "test".

There are three other interceptor specifications: @After, @Catch and @Finally. Read documentation for more details.