Documentation

You are viewing the documentation for the 2.7.0-M4 development release. The latest stable release series is 3.0.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(new Long(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 = new Integer(data.get("from")[0]);
		to = new Integer(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