dorado-core

the core module for dorado

License

License

GroupId

GroupId

ai.houyi
ArtifactId

ArtifactId

dorado-core
Last Version

Last Version

0.0.51
Release Date

Release Date

Type

Type

jar
Description

Description

dorado-core
the core module for dorado

Download dorado-core

How to add to project

<!-- https://jarcasting.com/artifacts/ai.houyi/dorado-core/ -->
<dependency>
    <groupId>ai.houyi</groupId>
    <artifactId>dorado-core</artifactId>
    <version>0.0.51</version>
</dependency>
// https://jarcasting.com/artifacts/ai.houyi/dorado-core/
implementation 'ai.houyi:dorado-core:0.0.51'
// https://jarcasting.com/artifacts/ai.houyi/dorado-core/
implementation ("ai.houyi:dorado-core:0.0.51")
'ai.houyi:dorado-core:jar:0.0.51'
<dependency org="ai.houyi" name="dorado-core" rev="0.0.51">
  <artifact name="dorado-core" type="jar" />
</dependency>
@Grapes(
@Grab(group='ai.houyi', module='dorado-core', version='0.0.51')
)
libraryDependencies += "ai.houyi" % "dorado-core" % "0.0.51"
[ai.houyi/dorado-core "0.0.51"]

Dependencies

compile (3)

Group / Artifact Type Version
io.netty : netty-all jar 4.1.27.Final
org.ow2.asm : asm jar 6.2
com.alibaba : fastjson jar 1.2.47

provided (4)

Group / Artifact Type Version
com.google.protobuf : protobuf-java jar 2.6.1
org.springframework.boot : spring-boot-autoconfigure-processor jar 2.1.1.RELEASE
org.springframework.boot : spring-boot-configuration-processor jar 2.1.1.RELEASE
org.springframework.boot : spring-boot-starter jar 2.1.1.RELEASE

test (1)

Group / Artifact Type Version
junit : junit jar 4.12

Project Modules

There are no modules declared in this project.

Dorado

简单、快速、轻量级的http restful server实现,基于Netty4和JDK1.8+

Features

  • HTTP/1.1 and HTTP/1.0协议支持
  • 内置JSON/Protobuf序列化支持,JSON序列化框架使用Fastjson, 依赖内置;
    如果使用protobuf序列化,需要自行添加protobuf依赖, protobuf版本2.x
  • Http路由支持, 路由path支持任意的java正则表达式,通过{pathVariable:regex}这种方式支持
  • 支持文件上传
  • Spring框架支持,默认支持注解方式初始化spring容器
  • SpringBoot集成
  • 集成swagger restful API文档生成工具
  • 过滤器支持,实现类似于spring mvc的interceptor功能
  • 支持全局异常处理
  • 支持统一响应格式处理

Latest version

0.0.51

Maven

<dependency>
    <groupId>ai.houyi</groupId>
    <artifactId>dorado-core</artifactId>
    <version>${dorado.version}</version>
</dependency>

Quick start

  • 最简单的Dorado rest server
public class Application {

    public static void main(String[] args) throws Exception {
        // create simple rest server, scanPackages现在可选,如果不设置
        //系统默认会自动找到main主类所在的包作为basePackage进行扫描
        DoradoServerBuilder.forPort(18888).build().start();
    }
}
  • 更多定制化参数服务器
public class Application {

    public static void main(String[] args) throws Exception {
        DoradoServerBuilder.forPort(18888).acceptors(2).ioWorkers(4)
                .minWorkers(10).maxWorkers(100)
                .backlog(1024)
                .maxConnection(500).maxPendingRequest(10000)
                .maxIdleTime(120).sendBuffer(256 * 1024)
                .recvBuffer(256 * 1024)
                .scanPackages("com.rtbstack.demo.controller",
                        "com.rtbstack.demo.controller1")
               .build().start();
    }
}
  • spring框架支持

    DoradoServerBuilder.forPort(port).springOn()

    由于框架本身不直接依赖spring框架,如果启用spring之后,务必自行添加spring框架相关依赖到项目中,否则系统启动会出现ClassNotFoundException

public class Application {

    public static void main(String[] args) throws Exception {
        DoradoServerBuilder.forPort(18888).springOn()
                .scanPackages("com.rtbstack.demo",
                        "com.rtbstack.demo.controller1")
               .build().start();
    }
}
  • Rest Controller
@Controller
@Path("/campaign")
public class CampaignController {

    @Path("/{id:[0-9]+}")
    @GET
    public Campaign newCampaign(int id) {
        Campaign campaign = new Campaign();
        campaign.setId(id);
        campaign.setName("test campaign");

        return campaign;
    }

    @Path("/name")
    public String campaignName() {
        return String.format("hello_campaign", "");
    }

    @POST
    public Campaign save(Campaign campaign) {
        System.out.println(campaign);
        return campaign;
    }

    @Path("/{id}")
    @DELETE
    public void deleteCampaign(int id) {
        System.out.println("delete campaign, id: " + id);
    }

    @GET
    @Path("/{id}")
    public Campaign getCampaign(int id) {
        return Campaign.builder().withId(12)
                .withName("网易考拉推广计划")
                .build();
    }
}
  • Filter
@FilterPath(include = "/campaign/*")
public class DemoFilter implements Filter {

    @Override
    public boolean preFilter(HttpRequest request, HttpResponse response) {
        System.out.println("execute demo filter");
        response.sendError(403, "Forbidden");
        return false;
    }
}
  • 文件上传支持
    支持文件上传很简单,只需要将controller方法的参数设置未MultipartFile或者MultipartFile[]即可,单文件用MultipartFile,
    多文件用MultipartFile[]
@Path("/file/upload")
@POST
public String uploadFile(MultipartFile[] fs,String name) {
    for(MultipartFile f:fs) {
        System.out.println(f.getName());
        System.out.println(f.getContentType());
        System.out.println(f.getSize());
    }
    return String.format("name: %s, file info: %s", name,f.toString());
}
  • 全局异常处理
    dorado支持用户通过自定义的类来进行全局异常处理,处理异常的方法名必须是handleException,类上面增加ExceptionAdvice注解

    @ExceptionAdvice
    public class TestExceptionAdvice {
    
    	@ExceptionType(MyException.class)
    	@Status(400) //Status注解来指定http响应状态码
    	public String handleException(MyException ex) {
    		return "cause: " + ex.getClass().getName() + "," + ex.getMessage();
    	}
    
    	@ExceptionType(Exception.class)
    	public String handleException(Exception ex) {
    		return "use default exception handler,cause: " + ex.getClass().getName() + "," + ex.getMessage();
    	}
    }
    
  • 全局统一响应格式处理
    在实际项目开发中,基于rest的服务一般都会定义统一的响应格式,如下面所示格式:

    {
    	"code": 0,
    	"data": data,
    	"msg": "OK"
    }

    为了避免在每个方法的时候都要执行相同的处理操作,dorado支持定义一个ai.houyi.dorado.rest.http.MethodReturnValueHandler来
    实现这个功能

    public class TestMethodReturnValueHandler implements MethodReturnValueHandler {
    
    	@Override
    	public Object handleMethodReturnValue(Object value, MethodDescriptor methodDescriptor) {
    		return TestResp.builder().withCode(0).withMsg("OK").withData(value).build();
    	}
    	
    	//自定义这个方法实现,用来控制哪些返回值需要被这个类进行处理
    	public boolean supportsReturnType(MethodDescriptor returnType) {
    	    return true;
    	}
    }
  • More examples

Please visit https://github.com/javagossip/dorado-examples

注解说明

类注解

注解类型 描述
Controller 控制器
Path 控制器访问Path
FilterPath 过滤器过滤路径,包括include以及exclude属性

方法注解

注解类型 描述
Path 资源访问路径,实际访问path为:controllerPath+methodPath
GET 方法仅支持Http GET请求
POST 方法仅支持Http POST请求
PUT 方法仅支持HTTP PUT请求
DELETE 方法仅支持HTTP DELETE请求
Consume 方法参数支持的MediaType, 如:application/json
Produce 方法响应MediaType, 如:application/json

方法参数注解

注解类型 描述 参数支持数据类型
RequestParam Query or Form parameter Primitive type&wrapper class,String
PathVariable Uri path variable, example: {var} Primitive type&wrapper class,String
HeaderParam Request header value Primitive type&wrapper class,String
CookieParam Request cookie value Primitive type&wrapper class,String
RequestBody Http request body String, byte[],InputStream or any serializable type

内置服务

SpringBoot集成

  • 添加dorado-spring-boot-starter核心依赖

    <dependency>
        <groupId>ai.houyi</groupId>
        <artifactId>dorado-spring-boot-starter</artifactId>
        <version>${dorado.version}</version>
    </dependency>
  • 基于springboot的dorado应用

    @SpringBootApplication
    @EnableDorado       //用这个注解开启dorado server
    public class SpringBootApplication {
    
        public static void main(String[] args) throws Exception {
            SpringApplication.run(SpringBootApplication.class, args);
        }
    }

    或者直接使用DoradoSpringBootApplication来替换SpringBootApplication和EnableDorado,如下:

      @DoradoSpringBootApplication
      public class SpringBootApplication {
    
            public static void main(String[] args) throws Exception {
                SpringApplication.run(SpringBootApplication.class, args);
            }
       }
  • Dorado框架的spring-boot配置参数

    参数名 描述 默认值
    dorado.port dorado server监听端口 18888
    dorado.backlog backlog队列大小 10000
    dorado.acceptors dorado acceptor count cpu核心数*2
    dorado.io-workers dorado io worker count cpu核心数*2
    dorado.min-workers 业务线程池最小线程数 100
    dorado.max-workers 业务线程池最大线程数 100
    dorado.max-connections 服务器最大连接数 100000
    dorado.max-pending-request 业务线程池队列长度 10000
    dorado.send-buffer send buffer size 256k
    dorado.recv-buffer recv buffer size 256k
    dorado.max-idle-time 连接最大空闲时间 8h
    dorado.max-packet-length http请求包体大小 1M

swagger集成

如果对swagger还不了解的话,参考:https://swagger.io/

  • 添加dorado-swagger-ui依赖
   <dependency>
       <groupId>ai.houyi</groupId>
       <artifactId>dorado-swagger-ui</artifactId>
       <version>${dorado.version}</version>
   </dependency>
  • 项目启动类中使用EnableSwagger注解启用swagger
@EnableSwagger
public class Application {
    public static void main(String[] args) throws Exception {
        // create simple rest server
        DoradoServerBuilder.forPort(18888).maxPacketLength(1024*1024*10)
           .build().start();
    }
}
  • 设置Api文档全局信息
    实现ai.houyi.dorado.swagger.ext.ApiContextBuilder接口
@Component //如果是集成spring或springboot环境的话,直接增加component注解即可
@Override
// 这里定制Api全局信息,如文档描述、license,contact等信息
public ApiContext buildApiContext() {
	Info info = new Info()
			.contact(new Contact().email("[email protected]").name("weiping wang")
					.url("http://github.com/javagossip/dorado"))
			.license(new License().name("apache v2.0").url("http://www.apache.org"))
			.termsOfService("http://swagger.io/terms/").description("Dorado服务框架api接口文档")
			.title("dorado demo api接口文档").version("1.0.0");

	//构造api访问授权的apiKey
	ApiKey apiKey = ApiKey.builder().withName("Authorization").withIn("header").build();
	ApiContext apiContext = ApiContext.builder().withApiKey(apiKey)
			.withInfo(info).build();

	return apiContext;
}

非spring环境需要在resources/META-INF/services下的ai.houyi.dorado.swagger.ext.ApiContextBuilder文件中增加如下配置:
ai.houyi.dorado.demo.ApiContextBuilderImpl

  • 在controller实现里面增加swagger相关的注解即可自动生成在线的api doc
@Controller
@Path("/campaign")
@Api(tags = { "营销活动管理" })
public class CampaignController {
    @Autowired
    private CampaignService campaignService;

    @Path("/{id:[0-9]+}")
    @GET
    @ApiOperation("新建campaign")
    public Campaign newCampaign(@PathVariable("id") int id) {
        Campaign campaign = new Campaign();
        campaign.setId(id);
        campaign.setName("test campaign");

        return campaign;
    }
}
  • spring-boot环境,可以直接引入dorado-swagger-spring-boot-starter依赖来进一步简化swagger的使用

     <dependency>
     	<groupId>ai.houyi</groupId>
     	<artifactId>dorado-swagger-spring-boot-starter</artifactId>
     	<version>${dorado.version}</version>
     </dependency> 

    然后在application.properties配置文件中增加如下配置即可:

     dorado.swagger.title=Zhuque's dashboard api
     dorado.swagger.description=${dorado.swagger.title}
     dorado.swagger.license=Apache License
     dorado.swagger.licenseUrl=http://www.apache.org/licenses/LICENSE-2.0
     dorado.swagger.contact.name=weiping wang
     [email protected]
     dorado.swagger.contact.url=https://github.com/javagossip
     
     //API全局认证配置
     dorado.swagger.apiKey.name=Authorization
     dorado.swagger.apiKey.in=header or query
  • 浏览器访问如下地址即可
    http://{host}:{port}/swagger-ui.html

性能测试

Versions

Version
0.0.51
0.0.50
0.0.49
0.0.48
0.0.47
0.0.44
0.0.42
0.0.41
0.0.37
0.0.36
0.0.35
0.0.34
0.0.33
0.0.32
0.0.29
0.0.28
0.0.27
0.0.25
0.0.24
0.0.23
0.0.22
0.0.18
0.0.17
0.0.16
0.0.15
0.0.14
0.0.13
0.0.12
0.0.11