Documentation

You are viewing the documentation for the 2.8.0-M6 development release. The latest stable release series is 2.7.x.

§Custom Routing

Play provides a mechanism to bind types from path or query string parameters.

§PathBindable

PathBindable allows to bind business objects from the URL path; this means we’ll be able to define routes like /user/3 to call an action such as the following:

§controller

public Result user(User user) {
  return ok(user.name);
}

The user parameter will automatically be retrieved using the id extracted from the URL path, e.g. with the following route definition:

§/conf/routes

GET     /user/:user            controllers.BinderApplication.user(user: javaguide.binder.models.User)

Any type T that implements PathBindable can be bound to/from a path parameter.
It defines abstract methods bind (build a value from the path) and unbind (build a path fragment from a value).

For a class like:

public class User implements PathBindable<User> {

  public Long id;
  public String name;

A simple example of the binder’s use binding the :id path parameter:

@Override
public User bind(String key, String id) {

  // findById meant to be lightweight operation
  User user = findById(Long.valueOf(id));
  if (user == null) {
    throw new IllegalArgumentException("User with id " + id + " not found");
  }
  return user;
}

@Override
public String unbind(String key) {
  return String.valueOf(id);
}

In this example findById method is invoked to retrieve User instance.

Note: in a real application such method should be lightweight and not involve e.g. DB access, because the code is called on the server IO thread and must be totally non-blocking. You would therefore for example use simple objects identifier as path bindable, and retrieve the real values using action composition.

§QueryStringBindable

A similar mechanism is used for query string parameters; a route like /age can be defined to call an action such as:

§controller

public Result age(AgeRange ageRange) {
  return ok(String.valueOf(ageRange.from));
}

The age parameter will automatically be retrieved using parameters extracted from the query string e.g. /age?from=1&to=10

Any type T that implements QueryStringBindable can be bound to/from query one or more query string parameters. Similar to PathBindable, it defines abstract methods bind and unbind.

For a class like:

public class AgeRange implements QueryStringBindable<AgeRange> {

  public Integer from;
  public Integer to;

A simple example of the binder’s use binding the :from and :to query string parameters:

@Override
public Optional<AgeRange> bind(String key, Map<String, String[]> data) {

  try {
    from = Integer.valueOf(data.get("from")[0]);
    to = Integer.valueOf(data.get("to")[0]);
    return Optional.of(this);

  } catch (Exception e) { // no parameter match return None
    return Optional.empty();
  }
}

@Override
public String unbind(String key) {
  return new StringBuilder().append("from=").append(from).append("&to=").append(to).toString();
}

Next: Extending Play