{"id":19125617,"url":"https://github.com/dmitmel/servario","last_synced_at":"2025-10-27T18:06:37.294Z","repository":{"id":95464145,"uuid":"60670771","full_name":"dmitmel/servario","owner":"dmitmel","description":"Very simple web-framework for making JVM-based web-apps","archived":false,"fork":false,"pushed_at":"2016-08-11T18:52:04.000Z","size":3436,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-03T09:46:00.506Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dmitmel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"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,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-06-08T05:26:17.000Z","updated_at":"2021-11-04T17:30:09.000Z","dependencies_parsed_at":"2023-03-19T01:57:21.819Z","dependency_job_id":null,"html_url":"https://github.com/dmitmel/servario","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmitmel%2Fservario","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmitmel%2Fservario/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmitmel%2Fservario/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmitmel%2Fservario/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dmitmel","download_url":"https://codeload.github.com/dmitmel/servario/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240190907,"owners_count":19762591,"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":[],"created_at":"2024-11-09T05:36:12.510Z","updated_at":"2025-10-27T18:06:37.184Z","avatar_url":"https://github.com/dmitmel.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# RaketaFramework\n\n#### This tutorial is too old. It'll be updated soon.\n\n## Contents\n\n1. [Hello World!](#hello-world)\n2. [Reading URL parameters](#reading-url-parameters)\n3. [Flexible URLs](#flexible-urls)\n4. [Receiving forms](#receiving-forms)\n5. [Downloads](#downloads)\n6. [License](#license)\n\n## Hello World!\n\nEveryone knows, that tutorials usually start from \"Hello World!\". I'll make exception. Our first program using\nRaketaFramework will show \"Hello World!\" twice :). Well, let's write some code:\n\n##### Main.java:\n```java\nimport github.dmitmel.raketaframework.handle.*;\nimport github.dmitmel.raketaframework.server.*;\n\npublic class Main {\n    public static void main(String[] args) {\n        HandlersList handlersList = new HandlersList(new HelloHandler());\n        Server server = new Server(handlersList);\n        server.start();\n    }\n\n    @RequestURLPattern(\"/hello\")\n    private static class HelloHandler implements RequestHandler {\n        @RequestMethod(\"GET\")\n        public String GET(RequestData requestData) {\n            return \"Hello World!\\r\\n\" + \n                    \"Hello World!\";\n        }\n    }\n}\n```\n\nMy congratulations! It's your first app! To run it from terminal, you can type something like this:\n\n```bash\njavac Main.java\njava -cp libs/RaketaFramework-1.0.jar Main\n```\n\nAnd to use app, you can open page `http://localhost:8080/hello`.\n\nWell, now I'll describe some things in code.\n\n### Code parts\n\n1. All request handlers (for example, `HelloHandler`) must implement empty marker-interface \n[`github.dmitmel.raketaframework.handle.RequestHandler`](https://github.com/dmitmel/RaketaFramework/blob/master/src/main/java/github/dmitmel/raketaframework/handle/RequestHandler.java)\nand be annotated by\n[`github.dmitmel.raketaframework.handle.RequestURLPattern`](https://github.com/dmitmel/RaketaFramework/blob/master/src/main/java/github/dmitmel/raketaframework/handle/RequestURLPattern.java).\nThis annotation can set Regexp for URLs, which can be handled by this handler. Groups are supported, you can read about them in\nnext parts.\n\n2. All handler methods must have 1 parameter and return value. You can read more detailed info about signatures\n[here](https://github.com/dmitmel/RaketaFramework/blob/master/src/main/java/github/dmitmel/raketaframework/handle/RequestMethod.java).\nAlso, they must be annotated using annotation\n[`github.dmitmel.raketaframework.handle.RequestMethod`](https://github.com/dmitmel/RaketaFramework/blob/master/src/main/java/github/dmitmel/raketaframework/handle/RequestMethod.java).\nThis annotation describes on which-method this Java-method will be used. But, you can't set handler for `OPTIONS` - \nthis method must return supported-methods.\n\n3. Class [`github.dmitmel.raketaframework.handle.RequestData`](https://github.com/dmitmel/RaketaFramework/blob/master/src/main/java/github/dmitmel/raketaframework/handle/RequestData.java)\nstores data about request.\n\n## Reading URL parameters\n\nWell, this's nice that we can send data to user, but what if user wants to talk with us? Let's make request handler\nwhich will return some greetings.\n\n```java\n// This class is inner class of Main\n@RequestURLPattern(\"/greet\")\nprivate static class Greeter implements RequestHandler {\n    @RequestMethod(\"GET\")\n    public Document GET(RequestData requestData) {\n        Document document = new Document();\n        \n        String who = requestData.getUrlParamOrElse(\"who\", \"World\");\n        int howMany = Integer.parseInt(requestData.getUrlParamOrElse(\"how-many\", \"1\"));\n\n        for (int i = 0; i \u003c howMany; i++) {\n            document.writeF(\"Hello, %s!\\r\\n\", who);\n        }\n        \n        return document;\n    }\n}\n```\n\nDon't forget to add new handler to handlers list!\n\n```java\n// First way (add handler in constructor):\nHandlersList handlersList = new HandlersList(new Greeter(), ...);\n// Second way (use method \"add\"):\nhandlersList.add(new Greeter());\n```\n\nWhat's new?\n\n1. Class [`github.dmitmel.raketaframework.handle.Document`](https://github.com/dmitmel/RaketaFramework/blob/master/src/main/java/github/dmitmel/raketaframework/handle/Document.java).\nIt works like stream or `java.lang.StringBuilder` - you can append it's data. It stores binary data, so you can put there\nimage.\n2. Methods [`RequestData#getUrlParamOrElse`](https://github.com/dmitmel/RaketaFramework/blob/master/src/main/java/github/dmitmel/raketaframework/handle/RequestData.java#L27)\nand [`RequestData#getUrlParam`](https://github.com/dmitmel/RaketaFramework/blob/master/src/main/java/github/dmitmel/raketaframework/handle/RequestData.java#L24).\nThese methods simply return one of params in URL.\n\nNow, let's use class `Greeter`!\n\n```bash\n# Imagine, that server has been already started\ncurl -i 'http://localhost:8080/greet?who=Dmitriy\u0026how-many=5'\n```\n\nOutput will be like this:\n\n```http\nHTTP/1.1 200 OK\nConnection: close\nServer: RaketaFramework/1.0.0 on Mac OS X 10.11.5\nContent-Length: 85\nDate: 8:14:04 PM\nContent-Type: text/plain\n\nHello, Dmitriy!\nHello, Dmitriy!\nHello, Dmitriy!\nHello, Dmitriy!\nHello, Dmitriy!\n```\n\n## Flexible URLs\n\nAs I said in the 1^st^ part,\n\n\u003e This annotation can set URL regexp, which can be handled by this handler. Groups are supported, you can read about them in\n\u003e next parts.\n\nYeah, I'm talking about Regexps, URLs, and annotation\n[`github.dmitmel.raketaframework.handle.RequestURLPattern`](https://github.com/dmitmel/RaketaFramework/blob/master/src/main/java/github/dmitmel/raketaframework/handle/RequestURLPattern.java).\nTime to talk about them!\n\nLet's imagine, that we're making handler for serving files. Client must send path of file. For example, he/she/it can\nsend path using URL param.\n\n```java\n// Usage: /load-file?path=...\n@RequestURLPattern(\"/load-file\")\nprivate static class FileLoader implements RequestHandler {\n    @RequestMethod(\"GET\")\n    public byte[] GET(RequestData requestData) {\n        String fileName = requestData.getUrlParam(\"path\");\n        byte[] bytes = /* Some code for loading files... */;\n        return bytes;\n    }\n}\n```\n\nBut, you can use Regexps!\n\n```java\n// Usage: /load-file/...\n@RequestURLPattern(\"/load-file/(.+)\")\nprivate static class FileLoader implements RequestHandler {\n    @RequestMethod(\"GET\")\n    public byte[] GET(RequestData requestData) {\n        String fileName = requestData.getMatcherGroup(0);\n        byte[] bytes = /* Some code for loading files... */;\n        return bytes;\n    }\n}\n```\n\nMethods [`RequestData#getMatcherGroup`](https://github.com/dmitmel/RaketaFramework/blob/master/src/main/java/github/dmitmel/raketaframework/handle/RequestData.java#L31)\nand [`RequestData#getMatcherGroupOrElse`](https://github.com/dmitmel/RaketaFramework/blob/master/src/main/java/github/dmitmel/raketaframework/handle/RequestData.java#L34)\nreturn match groups from URL Regexp.\n\n## Receiving forms\n\nMany-applications use forms. But how to receive them using RaketaFramework?\n\nLet's create simple greeting-app.\n\n##### In the Main.java:\n```java\n@RequestURLPattern(\"/form-greeter\")\nprivate static class FormGreeter implements RequestHandler {\n    @RequestMethod(\"GET\")\n    public String GET(RequestData requestData) {\n        throw new RedirectionThrowable(\"/load-file/index.html\");\n    }\n    \n    @RequestMethod(\"POST\")\n    public String POST(WebFormData form) {\n        if (form.getFormParam(\"name\") == null) throw new Error404();\n        if (form.getFormParam(\"greet\") == null) throw new Error404();\n        \n        return String.format(\"%s %s!\", form.getFormParam(\"greet\"), form.getFormParam(\"name\"));\n    }\n}\n```\n\n##### index.html:\n```html\n\u003c!DOCTYPE html\u003e\n\n\u003chtml\u003e\n    \u003chead\u003e\n        \u003ctitle\u003eGreet Form\u003c/title\u003e\n    \u003c/head\u003e\n\n    \u003cbody\u003e\n        \u003ch2\u003eHello, User!\u003cbr\u003e\u003c/h2\u003e\n        \n        \u003cform action=\"/form-greeter\" method=\"POST\"\u003e\n            \u003cp\u003eWhat's your name?\u003c/p\u003e\n            \u003cp\u003e\u003cinput type=\"text\" name=\"name\" value=\"World\" autocomplete=\"off\"\u003e\u003c/p\u003e\n            \u003cp\u003eWhat greeting would you like\u003cbr\u003eto have? (e.g. \"Hi\", \"Hello\")\u003c/p\u003e\n            \u003cp\u003e\u003cinput type=\"text\" name=\"greet\" value=\"Hello\" autocomplete=\"off\"\u003e\u003c/p\u003e\n            \u003cp\u003e\u003cinput type=\"submit\" value=\"Submit\"\u003e\u003c/p\u003e\n        \u003c/form\u003e\n    \u003c/body\u003e\n\u003c/html\u003e\n```\n\nThat's all! But, some notes about code:\n\n1. You can send to client HTTP errors. To use them, you must just throw exception with name \n[`Error${STATE}`](https://github.com/dmitmel/RaketaFramework/tree/master/src/gen/java/github/dmitmel/raketaframework/errors).\n2. To redirect user to other page, you must throw \n[`github.dmitmel.raketaframework.handle.RedirectionThrowable`](https://github.com/dmitmel/RaketaFramework/blob/master/src/main/java/github/dmitmel/raketaframework/handle/RedirectionThrowable.java)\n\n## Downloads\n\nBinaries - [`RaketaFramework-last.jar`](https://raw.githubusercontent.com/dmitmel/RaketaFramework/master/build/RaketaFramework-last.jar)\n\nTest binaries - [`RaketaFramework-last-test.jar`](https://raw.githubusercontent.com/dmitmel/RaketaFramework/master/build/RaketaFramework-last-test.jar)\n\nSources - [`RaketaFramework-last-src.jar`](https://raw.githubusercontent.com/dmitmel/RaketaFramework/master/build/RaketaFramework-last-src.zip)\n\n## License\nCopyright (c) 2016 WillThisFly.org\n\nLicensed under the Apache License, Version 2.0. You can get a copy at\n\n\u003cpre\u003e\u003ccode\u003e\u003ca href=\"http://www.apache.org/licenses/LICENSE-2.0\"\u003ehttp://www.apache.org/licenses/LICENSE-2.0\u003c/a\u003e\u003c/code\u003e\u003c/pre\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdmitmel%2Fservario","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdmitmel%2Fservario","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdmitmel%2Fservario/lists"}