{"id":13754016,"url":"https://github.com/pippo-java/pippo","last_synced_at":"2025-12-17T04:13:54.371Z","repository":{"id":22636668,"uuid":"25979437","full_name":"pippo-java/pippo","owner":"pippo-java","description":"Micro Java Web Framework","archived":false,"fork":false,"pushed_at":"2023-03-22T18:46:33.000Z","size":3896,"stargazers_count":785,"open_issues_count":64,"forks_count":127,"subscribers_count":41,"default_branch":"master","last_synced_at":"2025-04-12T04:49:37.393Z","etag":null,"topics":["java","microservice","web"],"latest_commit_sha":null,"homepage":"http://www.pippo.ro","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pippo-java.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null},"funding":{"github":"decebals"}},"created_at":"2014-10-30T16:23:30.000Z","updated_at":"2025-02-22T11:47:29.000Z","dependencies_parsed_at":"2024-01-17T15:03:02.723Z","dependency_job_id":"7194097c-fc47-4a57-8a22-cd8b555cf8c2","html_url":"https://github.com/pippo-java/pippo","commit_stats":null,"previous_names":["decebals/pippo"],"tags_count":30,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pippo-java%2Fpippo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pippo-java%2Fpippo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pippo-java%2Fpippo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pippo-java%2Fpippo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pippo-java","download_url":"https://codeload.github.com/pippo-java/pippo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254501555,"owners_count":22081528,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java","microservice","web"],"created_at":"2024-08-03T09:01:37.287Z","updated_at":"2025-12-17T04:13:49.337Z","avatar_url":"https://github.com/pippo-java.png","language":"Java","readme":"\u003cimg src=\"pippo-logo.svg\" width=\"250\"/\u003e\n\nMicro Java Web Framework\n=====================\n[![Join the chat at https://gitter.im/decebals/pippo](https://badges.gitter.im/decebals/pippo.svg)](https://gitter.im/decebals/pippo?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n[![GitHub Actions Status](https://github.com/pippo-java/pippo/actions/workflows/build.yml/badge.svg)](https://github.com/pippo-java/pippo/actions/workflows/build.yml)\n[![Coverage Status](https://coveralls.io/repos/pippo-java/pippo/badge.svg?branch=master\u0026service=github)](https://coveralls.io/github/pippo-java/pippo?branch=master)\n[![Maven Central](http://img.shields.io/maven-central/v/ro.pippo/pippo.svg)](http://search.maven.org/#search|ga|1|ro.pippo)\n\n\u003c!--\n[![Issue Stats](http://www.issuestats.com/github/pippo-java/pippo/badge/issue?style=flat)](http://www.issuestats.com/github/pippo-java/pippo)\n[![Issue Stats](http://www.issuestats.com/github/pippo-java/pippo/badge/pr?style=flat)](http://www.issuestats.com/github/pippo-java/pippo)\n--\u003e\n\n\nIt's an open source (Apache License) micro web framework in Java, with minimal dependencies and a quick learning curve.     \nThe goal of this project is to create a micro web framework in Java that should be easy to use and hack.      \nThe size of `pippo-core` is only __140 KB__ and the size of `pippo-controller` (optional) is only __45 KB__.\n\nSample code\n---------------\n\n#### 1. Routes approach\n\nFirst we must create an __Application__ and add some routes:  \n\n```java\npublic class BasicApplication extends Application {\n\n    @Override\n    protected void onInit() {\n        // send 'Hello World' as response\n        GET(\"/\", routeContext -\u003e routeContext.send(\"Hello World\"));\n\n        // send a file as response\n        GET(\"/file\", routeContext -\u003e routeContext.send(new File(\"pom.xml\")));\n\n        // send a json as response\n        GET(\"/json\", routeContext -\u003e {\n            Contact contact = createContact();\n            routeContext.json().send(contact);\n        });\n\n        // send xml as response\n        GET(\"/xml\", routeContext -\u003e {\n            Contact contact = createContact();\n            routeContext.xml().send(contact);\n        });\n\n        // send an object and negotiate the Response content-type, default to XML\n        GET(\"/negotiate\", routeContext -\u003e {\n            Contact contact = createContact();\n            routeContext.xml().negotiateContentType().send(contact);\n        });\n\n        // send a template with name \"hello\" as response\n        GET(\"/template\", routeContext -\u003e {\n            routeContext.setLocal(\"greeting\", \"Hello\");\n            routeContext.render(\"hello\");\n        });\n    }\n\n    private Contact createContact() {\n        return new Contact()\n            .setId(12345)\n            .setName(\"John\")\n            .setPhone(\"0733434435\")\n            .setAddress(\"Sunflower Street, No. 6\");\n    }\n\n}\n```\n\nwhere `Contact` is a simple POJO:\n\n```java\npublic class Contact  {\n\n    private int id;\n    private String name;\n    private String phone;\n    private String address;\n\n    // getters and setters\n\n}\n```\n\nThe second step is to choose your favorite [server](http://www.pippo.ro/doc/server.html),\n[template engine](http://www.pippo.ro/doc/templates.html)\nand [content type engine](http://www.pippo.ro/doc/content-types.html).  \nFor example, I will choose `Jetty` as server, `Freemarker` as template engine, `Jackson` as JSON engine and `JAXB` as XML engine.  \nMy Maven `pom.xml` looks like:\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ero.pippo\u003c/groupId\u003e\n    \u003cartifactId\u003epippo-core\u003c/artifactId\u003e\n    \u003cversion\u003e${pippo.version}\u003c/version\u003e\n\u003c/dependency\u003e\n\n\u003cdependency\u003e\n    \u003cgroupId\u003ero.pippo\u003c/groupId\u003e\n    \u003cartifactId\u003epippo-jetty\u003c/artifactId\u003e\n    \u003cversion\u003e${pippo.version}\u003c/version\u003e\n\u003c/dependency\u003e\n\n\u003cdependency\u003e\n    \u003cgroupId\u003ero.pippo\u003c/groupId\u003e\n    \u003cartifactId\u003epippo-freemarker\u003c/artifactId\u003e\n    \u003cversion\u003e${pippo.version}\u003c/version\u003e\n\u003c/dependency\u003e\n\n\u003cdependency\u003e\n    \u003cgroupId\u003ero.pippo\u003c/groupId\u003e\n    \u003cartifactId\u003epippo-jackson\u003c/artifactId\u003e\n    \u003cversion\u003e${pippo.version}\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nThe last step it's to start __Pippo__ with your application as parameter:\n\n```java\npublic class BasicDemo {\n\n    public static void main(String[] args) {\n        Pippo pippo = new Pippo(new BasicApplication());\n        pippo.start();\n    }\n\n}\n```\n\nPippo launches the embedded web server (found in your classpath) and makes the application available on port `8338` (default value).\nOpen your internet browser and check the routes declared in Application:\n\n - `http://localhost:8338`\n - `http://localhost:8338/file`\n - `http://localhost:8338/json`\n - `http://localhost:8338/xml`\n - `http://localhost:8338/negotiate`\n - `http://localhost:8338/template`\n\n#### 2. Controllers approach\n\nDefine controller(s):\n\n```java\n@Path(\"/contacts\")\n@Logging\npublic class ContactsController extends Controller {\n\n    private ContactService contactService;\n\n    public ContactsController() {\n        contactService = new InMemoryContactService();\n    }\n\n    @GET\n    @Named(\"index\")\n//    @Produces(Produces.HTML)\n    @Metered\n    @Logging\n    public void index() {\n        // inject \"user\" attribute in session\n        getRouteContext().setSession(\"user\", \"decebal\");\n\n        // send a template with name \"contacts\" as response\n        getResponse()\n            .bind(\"contacts\", contactService.getContacts())\n            .render(\"contacts\");\n    }\n\n    @GET(\"/uriFor/{id: [0-9]+}\")\n    @Named(\"uriFor\")\n    @Produces(Produces.TEXT)\n    @Timed\n    public String uriFor(@Param int id, @Header String host, @Session String user) {\n        System.out.println(\"id = \" + id);\n        System.out.println(\"host = \" + host);\n        System.out.println(\"user = \" + user);\n\n        Map\u003cString, Object\u003e parameters = new HashMap\u003c\u003e();\n        parameters.put(\"id\", id);\n\n        String uri = getApplication().getRouter().uriFor(\"api.get\", parameters);\n\n        return \"id = \" + id + \"; uri = \" + uri;\n    }\n\n    @GET(\"/api\")\n    @Named(\"api.getAll\")\n    @Produces(Produces.JSON)\n    @NoCache\n    public List\u003cContact\u003e getAll() {\n        return contactService.getContacts();\n    }\n\n    @GET(\"/api/{id: [0-9]+}\")\n    @Named(\"api.get\")\n    @Produces(Produces.JSON)\n    public Contact get(@Param int id) {\n        return contactService.getContact(id);\n    }\n\n}\n```\n\n```java\n@Path(\"/files\")\npublic class FilesController extends Controller {\n\n    @GET\n    public void index() {\n        // send a template with name \"files\" as response\n        getRouteContext().render(\"files\");\n    }\n\n    @GET(\"/download\")\n    public File download() {\n        // send a file as response\n        return new File(\"pom.xml\");\n    }\n\n    @POST(\"/upload\")\n    @Produces(Produces.TEXT)\n    public String upload(FileItem file) {\n        // send a text (the info about uploaded file) as response\n//        return file.toString();\n        return new StringBuilder()\n            .append(file.getName()).append(\"\\n\")\n            .append(file.getSubmittedFileName()).append(\"\\n\")\n            .append(file.getSize()).append(\"\\n\")\n            .append(file.getContentType())\n            .toString();\n    }\n\n}\n```\n\nAdd controller(s) in your application:\n\n```java\npublic class BasicApplication extends ControllerApplication {\n\n    @Override\n    protected void onInit() {\n        addControllers(ContactsController.class); // one instance for EACH request\n        // OR\n        addControllers(new ContactsController()); // one instance for ALL requests\n\n        addControllers(FilesController.class);\n    }\n\n}\n```\n\nDon't forget that the `Controller` concept is included in `pippo-controller` module so you must add this module as dependency in your project.\n\nDocumentation\n---------------\nDocumentation is available on [pippo.ro](http://www.pippo.ro)\n\nDemo\n---------------\nDemo applications are available on [pippo-demo](https://github.com/pippo-java/pippo-demo)   \nFor a real life application built with Pippo please look at [Web Accounting - Pippo Demo](https://github.com/pippo-java/matilda)\n","funding_links":["https://github.com/sponsors/decebals"],"categories":["web","开发框架"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpippo-java%2Fpippo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpippo-java%2Fpippo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpippo-java%2Fpippo/lists"}