Fork me on GitHub

Another approach to handling a request and producing a response is using Controllers. After routing has determined what controller to use, an action method will be invoked. In Pippo, controllers are instances of Controller.

How to use

Defining a new controller is simple:

public class ContactsController extends Controller {

    private ContactService contactService;

    public ContactsController() {
        contactService = new InMemoryContactService();

//    @Produces(Produces.HTML)
    public void index() {
        // inject "user" attribute in session
        getRouteContext().setSession("user", "decebal");

        // send a template with name "contacts" as response
            .bind("contacts", contactService.getContacts())

    @GET("/uriFor/{id: [0-9]+}")
    public String uriFor(@Param int id, @Header String host, @Session String user) {
        System.out.println("id = " + id);
        System.out.println("host = " + host);
        System.out.println("user = " + user);

        Map<String, Object> parameters = new HashMap<>();
        parameters.put("id", id);

        String uri = getApplication().getRouter().uriFor("api.get", parameters);

        return "id = " + id + "; uri = " + uri;

    public List<Contact> getAll() {
        return contactService.getContacts();

    @GET("/api/{id: [0-9]+}")
    public Contact get(@Param int id) {
        return contactService.getContact(id);

public class FilesController extends Controller {

    public void index() {
        // send a template with name "files" as response

    public File download() {
        // send a file as response
        return new File("pom.xml");

    public String upload(FileItem file) {
        // send a text (the info about uploaded file) as response
//        return file.toString();
        return new StringBuilder()


Methods attached to the controller (for example index from above snippet) are known as action methods. When Pippo receives a request, it will create a new instance of the controller and call the appropriate action method. You can register a controller’s action in application with a simple line:

public class MyApplication extends ControllerApplication {

    protected void onInit() {
        // add controller(s)
        addControllers(ContactsController.class); // one instance for EACH request
        // or
        addControllers(new ContactsController()); // one instance for ALL requests

public class ControllerDemo {

    public static void main(String[] args) {
        Pippo pippo = new Pippo(new MyApplication());


DON’T forget to add pippo-controller module as dependency in your project. If you use Maven, your pom.xml must contains above lines:


Parameter name

The Controller module may depend on the -parameters flag of the Java 8 javac compiler. This flag embeds the names of method parameters in the generated .class files.

By default Java 8 does not compile with this flag set so you must specify javac compiler arguments for Maven and your IDE.


So, if you you compile with -parameters flag you can define the controller method like:

void invoice(@Param orderId) { ... }

instead of:

void invoice(@Param("orderId") orderId) { ... }

If you use the first variant without -parameters flag on compile, you will receive an exception like:

ro.pippo.core.PippoRuntimeException: Method 'acme.controller.MyController::invoice' parameter 0 does not specify a name!
	at ro.pippo.controller.extractor.ParamExtractor.getParameterName(
	at ro.pippo.controller.extractor.ParamExtractor.extract(
	at ro.pippo.controller.ControllerRouteHandler.prepareMethodParameters(
	at ro.pippo.controller.ControllerRouteHandler.handle(
	at ro.pippo.core.route.DefaultRouteContext.handleRoute(
	at ro.pippo.core.route.RouteDispatcher.onRouteDispatch(
	at ro.pippo.core.route.RouteDispatcher.dispatch(
	at ro.pippo.core.PippoFilter.processRequest(

Implementation details

Advanced features (Extractor, Interceptor, …) and technical aspects are presented in details here.

You can see a demo here