§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