{"id":13694802,"url":"https://github.com/TogetherOS/cicada","last_synced_at":"2025-05-03T04:30:57.971Z","repository":{"id":33285163,"uuid":"146691974","full_name":"TogetherOS/cicada","owner":"TogetherOS","description":"🚀 Fast lightweight HTTP service framework.","archived":false,"fork":false,"pushed_at":"2023-07-17T21:53:48.000Z","size":289,"stargazers_count":951,"open_issues_count":12,"forks_count":211,"subscribers_count":61,"default_branch":"master","last_synced_at":"2024-11-12T21:39:18.392Z","etag":null,"topics":["high-performance","http","json","lightweight","netty4"],"latest_commit_sha":null,"homepage":"https://crossoverjie.top/categories/cicada/","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/TogetherOS.png","metadata":{"files":{"readme":"README-ZH.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}},"created_at":"2018-08-30T03:41:22.000Z","updated_at":"2024-10-28T02:33:40.000Z","dependencies_parsed_at":"2022-07-11T00:00:29.944Z","dependency_job_id":"4cf90aa0-75ec-4715-a914-209ede08753c","html_url":"https://github.com/TogetherOS/cicada","commit_stats":null,"previous_names":["crossoverjie/cicada"],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TogetherOS%2Fcicada","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TogetherOS%2Fcicada/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TogetherOS%2Fcicada/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TogetherOS%2Fcicada/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TogetherOS","download_url":"https://codeload.github.com/TogetherOS/cicada/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252144504,"owners_count":21701425,"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":["high-performance","http","json","lightweight","netty4"],"created_at":"2024-08-02T17:01:43.005Z","updated_at":"2025-05-03T04:30:56.269Z","avatar_url":"https://github.com/TogetherOS.png","language":"Java","funding_links":[],"categories":["Java","开发框架"],"sub_categories":[],"readme":"\n\u003cdiv align=\"center\"\u003e  \n\n\u003cimg src=\"https://i.loli.net/2020/02/23/oTrqAsjxV4wH3IE.png\"  /\u003e \n\u003cbr/\u003e\n\n[![Build Status](https://travis-ci.org/crossoverJie/cicada.svg?branch=master)](https://travis-ci.org/crossoverJie/cicada)\n[![](https://maven-badges.herokuapp.com/maven-central/top.crossoverjie.opensource/cicada-core/badge.svg)](https://maven-badges.herokuapp.com/maven-central/top.crossoverjie.opensource/cicada-core/)\n[![QQ群](https://img.shields.io/badge/QQ%E7%BE%A4-787381170-yellowgreen.svg)](https://jq.qq.com/?_wv=1027\u0026k=5HPYvQk)\n\n[qq0groupsvg]: https://img.shields.io/badge/QQ%E7%BE%A4-787381170-yellowgreen.svg\n[qq0group]: https://jq.qq.com/?_wv=1027\u0026k=5HPYvQk\n\n\n📘[特性](#features) |🌁[快速启动](#quick-start) | 🏖[性能测试](#performance-test) | 🌈[更新记录](#changelog) | 💡 [联系作者](#contact-author)|🇦🇺[English](https://github.com/TogetherOS/cicada)\n\n\u003c/div\u003e\u003cbr\u003e\n\n\n## 简介\n\n基于 Netty4 实现的快速、轻量级 WEB 框架；没有过多的依赖，核心 jar 包仅 `30KB`。\n\n如果你感兴趣，请点 [Star](https://github.com/crossoverJie/cicada/stargazers)。\n\n## 特性\n\n- [x] 代码简洁，没有过多依赖。\n- [x] 一行代码即可启动 HTTP 服务。\n- [x] [自定义拦截器](#自定义拦截器)。\n- [x] [自定义全局异常](#自定义全局异常).\n- [x] 灵活的传参方式。\n- [x] `json` 响应格式。\n- [x] [自定义配置](#自定义配置)。\n- [x] 多种响应方式。\n- [x] 内置可插拔 `IOC` 容器。\n- [x] [`Cookie` 支持](#cookie-支持)。\n- [ ] 文件上传。\n\n\n## 快速启动\n\n创建一个 maven 项目，引入核心依赖。\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003etop.crossoverjie.opensource\u003c/groupId\u003e\n    \u003cartifactId\u003ecicada-core\u003c/artifactId\u003e\n    \u003cversion\u003ex.y.z\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n当然也推荐额外再引入一个 `IOC` 容器插件：\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003etop.crossoverjie.opensource\u003c/groupId\u003e\n    \u003cartifactId\u003ecicada-ioc\u003c/artifactId\u003e\n    \u003cversion\u003e2.0.4\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n启动类：\n\n```java\npublic class MainStart {\n\n    public static void main(String[] args) throws InterruptedException {\n        CicadaServer.start(MainStart.class,\"/cicada-example\") ;\n    }\n}\n```\n\n### 配置业务 Action\n\n```java\n@CicadaAction(\"routeAction\")\npublic class RouteAction {\n\n    private static final Logger LOGGER = LoggerBuilder.getLogger(RouteAction.class);\n\n\n    @CicadaRoute(\"getUser\")\n    public void getUser(DemoReq req){\n\n        LOGGER.info(req.toString());\n        WorkRes\u003cDemoReq\u003e reqWorkRes = new WorkRes\u003c\u003e() ;\n        reqWorkRes.setMessage(\"hello =\" + req.getName());\n        CicadaContext.getContext().json(reqWorkRes) ;\n    }\n\n    @CicadaRoute(\"getInfo\")\n    public void getInfo(DemoReq req){\n\n        WorkRes\u003cDemoReq\u003e reqWorkRes = new WorkRes\u003c\u003e() ;\n        reqWorkRes.setMessage(\"getInfo =\" + req.toString());\n        CicadaContext.getContext().json(reqWorkRes) ;\n    }\n\n    @CicadaRoute(\"getReq\")\n    public void getReq(CicadaContext context,DemoReq req){\n\n        WorkRes\u003cDemoReq\u003e reqWorkRes = new WorkRes\u003c\u003e() ;\n        reqWorkRes.setMessage(\"getReq =\" + req.toString());\n        context.json(reqWorkRes) ;\n    }\n\n\n\n}\n```\n\n启动应用访问 [http://127.0.0.1:5688/cicada-example/routeAction/getUser?id=1234\u0026name=zhangsan](http://127.0.0.1:5688/cicada-example/routeAction/getUser?id=1234\u0026name=zhangsan)\n\n```json\n{\"message\":\"hello =zhangsan\"}\n```\n\n## Cicada 上下文\n\n通过 `context.json(),context.text()` 方法可以选择不同的响应方式。\n\n```java\n@CicadaAction(\"routeAction\")\npublic class RouteAction {\n\n    private static final Logger LOGGER = LoggerBuilder.getLogger(RouteAction.class);\n\n    @CicadaRoute(\"getUser\")\n    public void getUser(DemoReq req){\n\n        LOGGER.info(req.toString());\n        WorkRes\u003cDemoReq\u003e reqWorkRes = new WorkRes\u003c\u003e() ;\n        reqWorkRes.setMessage(\"hello =\" + req.getName());\n        CicadaContext.getContext().json(reqWorkRes) ;\n    }\n    \n    @CicadaRoute(\"hello\")\n    public void hello() throws Exception {\n        CicadaContext context = CicadaContext.getContext();\n\n        String url = context.request().getUrl();\n        String method = context.request().getMethod();\n        context.text(\"hello world url=\" + url + \" method=\" + method);\n    }    \n\n\n}\n```\n\n\n## Cookie 支持\n\n### 设置 Cookie\n\n```java\nCookie cookie = new Cookie() ;\ncookie.setName(\"cookie\");\ncookie.setValue(\"value\");\nCicadaContext.getResponse().setCookie(cookie);\n```\n\n### 获取 Cookie\n\n```java\nCookie cookie = CicadaContext.getRequest().getCookie(\"cookie\");\nlogger.info(\"cookie = \" + cookie.toString());\n```\n\n## 自定义配置\n\n`cicada` 默认会读取 classpath 下的 `application.properties` 配置文件。\n\n同时也可以自定义配置文件。\n\n只需要继承 `top.crossoverjie.cicada.server.configuration.AbstractCicadaConfiguration`\n\n并传入配置文件名称即可。比如：\n\n\n```java\npublic class RedisConfiguration extends AbstractCicadaConfiguration {\n\n\n    public RedisConfiguration() {\n        super.setPropertiesName(\"redis.properties\");\n    }\n\n}\n\npublic class KafkaConfiguration extends AbstractCicadaConfiguration {\n\n    public KafkaConfiguration() {\n        super.setPropertiesName(\"kafka.properties\");\n    }\n\n\n}\n```\n\n![](https://ws3.sinaimg.cn/large/0069RVTdgy1fv5mw7p5nvj31by0fo76t.jpg)\n\n### 获取配置\n\n按照如下方式即可获取自定义配置：\n\n```java\nKafkaConfiguration configuration = (KafkaConfiguration) getConfiguration(KafkaConfiguration.class);\nRedisConfiguration redisConfiguration = (RedisConfiguration) ConfigurationHolder.getConfiguration(RedisConfiguration.class);\nApplicationConfiguration applicationConfiguration = (ApplicationConfiguration) ConfigurationHolder.getConfiguration(ApplicationConfiguration.class);\n\nString brokerList = configuration.get(\"kafka.broker.list\");\nString redisHost = redisConfiguration.get(\"redis.host\");\nString port = applicationConfiguration.get(\"cicada.port\");\n\nLOGGER.info(\"Configuration brokerList=[{}],redisHost=[{}] port=[{}]\",brokerList,redisHost,port);\n```\n\n### 外置配置文件\n\n当然在特殊环境中(`dev/test/pro`)也可以读取外置配置文件。只需要加上启动参数，保证参数名称和文件名一致即可。\n\n```shell\n-Dapplication.properties=/xx/application.properties\n-Dkafka.properties=/xx/kakfa.properties\n-Dredis.properties=/xx/redis.properties\n```\n\n## 自定义拦截器\n\n实现 `top.crossoverjie.cicada.example.intercept.CicadaInterceptor` 接口。\n\n```java\n@Interceptor(value = \"executeTimeInterceptor\")\npublic class ExecuteTimeInterceptor implements CicadaInterceptor {\n\n    private static final Logger LOGGER = LoggerBuilder.getLogger(ExecuteTimeInterceptor.class);\n\n    private Long start;\n\n    private Long end;\n\n    @Override\n    public boolean before(Param param) {\n        start = System.currentTimeMillis();\n        return true;\n    }\n\n    @Override\n    public void after(Param param) {\n        end = System.currentTimeMillis();\n\n        LOGGER.info(\"cast [{}] times\", end - start);\n    }\n}\n```\n\n## 自定义全局异常\n\n现在你可以自定义全局异常，就像这样：\n\n```java\n@CicadaBean\npublic class ExceptionHandle implements GlobalHandelException {\n    private final static Logger LOGGER = LoggerBuilder.getLogger(ExceptionHandle.class);\n\n    @Override\n    public void resolveException(CicadaContext context, Exception e) {\n        LOGGER.error(\"Exception\", e);\n        WorkRes workRes = new WorkRes();\n        workRes.setCode(\"500\");\n        workRes.setMessage(e.getClass().getName());\n        context.json(workRes);\n    }\n}\n```\n\n\n## 性能测试\n\n![](https://ws4.sinaimg.cn/large/006tNbRwly1fv4luap7w0j31kw0iwdnu.jpg)\n\n\u003e 测试条件：100 threads and 100 connections ;1G RAM/4 CPU。\n\n**每秒将近 10W 请求。**\n\n## 更新记录\n\n### v2.0.2\n- 修复 [#40](https://github.com/TogetherOS/cicada/issues/40) \n- 新增全局异常接口。\n- 通过类类型获取 bean。\n\n### v2.0.1\n- 更新 Logo ,美化日志。\n- 支持 `Cookie`\n\n### v2.0.0\n- 修复 [#12](https://github.com/TogetherOS/cicada/issues/12) [#22](https://github.com/TogetherOS/cicada/issues/22) [#28](28)\n- 更加灵活的路由方式。\n- 内置可插拔 `IOC` 容器。\n\n### v1.0.3\n\n- 修复 [#9](https://github.com/TogetherOS/cicada/issues/9)\n- 修复 [#8](https://github.com/TogetherOS/cicada/issues/8),多种响应方式。\n- 重构了核心代码，新增上下文环境。\n- 优雅停机。\n\n### v1.0.2\n\n- 修复 [#6](https://github.com/TogetherOS/cicada/issues/6)\n- 自定义配置文件。\n- 灵活使用配置。\n- 重构代码。\n\n## 联系作者\n\n\n\u003e crossoverJie#gmail.com\n\n![qrcode_for_gh_3a954a025f10_258.jpg](https://i.loli.net/2019/07/09/5d245f3e955ce61699.jpg) \n\n## 特别感谢\n\n- [Netty](https://github.com/netty/netty)\n- [blade](https://github.com/lets-blade/blade)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FTogetherOS%2Fcicada","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FTogetherOS%2Fcicada","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FTogetherOS%2Fcicada/lists"}