Fork me on GitHub

Most server-side Java applications (e.g. web or service-oriented) are intended to run within a container. The traditional way to package these apps for distribution is to bundle them as a WAR file. Of course you can use the above model for your application development or you can use the simple way. Rather than your application being deployed to a container, an embedded container is deployed within the application itself. Pippo comes with Jetty as embedded web server. You can choose another container if you want (for example Tomcat).

See below the classic Hello World in Pippo using the default web server:

public class HelloWorld {

    public static void main(String[] args) {
        Pippo pippo = new Pippo();
        pippo.GET("/", routeContext -> routeContext.send("Hello World!"));


You can run HelloWorld class from your IDE (or command line) as a normal (desktop) application. The default port for embedded web server is 8338 so open your internet browser and type http://localhost:8338 to see the result.

You can change some aspects of the embedded web server using WebServerSettings:

Pippo pippo = new Pippo();

In above snippet I changed programmatically the port to 8081.

Probably the best approach to specify the server port for an embedded server is via application settings.
Simple set the server.port variable from your src\main\resources\main\conf\ with your value:

# Control the port that Pippo binds
server.port = 8081

Pippo detects automatically the template engine using ServiceLoader.
Pippo comes (out of the box) with some web servers:

To use one of these servers just add a dependency in your project:


If you need to create support for another embedded web server that is not implemented in Pippo or third-party modules than all you need to do is to implement WebServer or to extends AbstractWebServer.

If you want to make your embedded server plugable for Pippo than you must add @MetaInfServices(WebServer.class) annotation to your class

public class JettyServer extends AbstractWebServer<JettySettings> {

    // attributes, methods, ...

Are some situations when the settings provided by an WebServer instance are not enough for you.
In these situations you need to create a custom WebServer.
The idea is to create a custom WebServer if you want to override some aspects (methods) of that server or if you want free access to the servlet container (Jetty, Tomcat, …).

Show below the code for a JettyServer with persistent sessions

public class MyJettyServer extends JettyServer {

    protected ServletContextHandler createPippoHandler() {
        ServletContextHandler handler = super.createPippoHandler();

        // set session manager with persistence
        HashSessionManager sessionManager = new HashSessionManager();
        try {
            sessionManager.setStoreDirectory(new File("sessions-storage"));
        } catch (IOException e) {
            throw new PippoRuntimeException(e);
        sessionManager.setLazyLoad(true); // other possible option
        handler.setSessionHandler(new SessionHandler(sessionManager));

        return handler;


public class Main {

    public static void main(String[] args) {
        new Pippo(new MyApplication()).setServer(new MyJettyServer()).start();


The WebServer abstraction allows you to add a Servlet, Filter or ServletContextListener in any supported servlet container via addListener(Class<? extends ServletContextListener> listener) method.
For the same task but more modular you can use WebServerInitializer.
Below I present you a code snippet that add a servlet to Pippo:

import org.kohsuke.MetaInfServices;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ro.pippo.core.WebServerInitializer;

import javax.servlet.ServletContext;
import javax.servlet.ServletRegistration;

public class ServletAppender implements WebServerInitializer {

    private static final Logger log = LoggerFactory.getLogger(ServletAppender.class);

    public void init(ServletContext servletContext) {
        ServletRegistration.Dynamic demoServlet = servletContext.addServlet("demo", DemoServlet.class);
        // other possible settings for demoServlet

        log.debug("Added servlet '{}' to '{}'", demoServlet.getClassName(), demoServlet.getMappings().iterator().next());

    public void destroy(ServletContext servletContext) {
        // do nothing

import ro.pippo.core.Pippo;

import static ro.pippo.core.route.Route.GET;

public class ServletDemo {

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

        // set pippo filter path

        // add route
        pippo.GET("/", routeContext -> routeContext.send("Hello from Pippo route!"));



DON’T forget to add @MetaInfServices on your implementation of WebServerInitializer!
The full code is available in pippo-demo-servlet project.

A more complex demo project that shows you how to integrate Jersey is available in pippo-demo-jersey project. This demo is the code source of the article Pippo and Jersey (JAX-RS): A Match Made in Heaven that is availables on DZone.