§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 that in real world 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.of(null);
}
}
@Override
public String unbind(String key) {
return new StringBuilder()
.append("from=")
.append(from)
.append("&to=")
.append(to)
.toString();
}
Next: Extending Play