1.为什么需要轻量级http server框架
由于spring 全家桶强大的功能,大多数情况下,我们在创建http服务的时候,会使用spring提供的Http服务框架。那么大家都知道,凡事都有两面性,一个功能强大的产品,必然在一定程度上,多了很多冗余,牺牲了性能,易用性等。大多数时候,我们创建的是web服务端,这个时候,使用spring全家桶是没什么问题的,其强大的功能,可以帮我们减少很多工作量,相对于其牺牲的少来性能以及带来的一点复杂度而言,是很划算的。但是,并不是所有的项目都是web项目,如果我们只是项目中需要提供http的少量接口,让第三方去调用呢?这个时候使用spring 就有点不合时宜了,毕竟如果为了区区几个接口,进入庞大的srping框架,是很不划算的。那么这个时候,我们就需要一个轻量的java hhtp 服务框架,在满足我们业务需求的同时,不会过多的增加项目依赖以及复杂度。
2.为什么选择javalin
我们相对基础的工具中使用hhtp服务,大部分时候,只是用来提供几个简单的接口。由于不是一个web为主的项目,所以,我们需要一个,可以在任意地方通过编程注册接口,类似nodejs的Koa ,或者golang的echo 这种,简单又满足基本应用的的框架。对比了多种java的http 服务,选择了javalin。
我们可以看到javalin 官网的实例代码
import io.javalin.Javalin;
public class HelloWorld {
public static void main(String[] args) {
var app = Javalin.create(/*config*/)
.get("/", ctx -> ctx.result("Hello World"))
.start(7070);
}
}
的确很简单,几行代码即可。
<dependency>
<groupId>io.javalin</groupId>
<artifactId>javalin</artifactId>
<version>6.1.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.9</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.10</version>
<optional>true</optional>
</dependency>
用官网代码创建一个服务,启动可见
服务启动只需要127ms,速度还是可以的。当然,这是因为只有一个Http服务,并没有其他的依赖。
通过url 可访问。
3.2路由分组
public static void main(String[] args) {
Javalin.create(javalinConfig -> {
javalinConfig.router.apiBuilder(() -> {
ApiBuilder.path("/users", () -> {
ApiBuilder.get("/a", (context) -> context.result("a"));
ApiBuilder.get("/b", (context) -> context.result("b"));
});
});
}).start(7070);
}
3.3过滤器
javalin中提供了before和after 函数,用在执行函数的前置和后置,我们可以用其来做
public static void main(String[] args) {
Javalin app = Javalin.create(/*config*/)
.before("/",ctx -> {
ctx.result("before");
})
.get("/", ctx -> {
ctx.result("Hello World");
})
.after("/",ctx -> {
ctx.result("after");
})
.start(7070);
}
中断处理,直接抛出异常,通过exception捕获异常,并进行处理
public static void main(String[] args) {
Javalin app = Javalin.create(/*config*/)
.before("/", ctx -> {
if (ctx.method() == HandlerType.GET) {
throw new RuntimeException("Something went wrong");
}
})
.get("/", ctx -> {
ctx.result("Hello World");
})
.exception(Exception.class, (e, ctx) -> {
ctx.result("server exception");
ctx.status(500);
})
.start(7070);
}
除去before和after还有beforeMatched和afterMatched ,两者略有区别,注意区分
3.4 其他
以上功能已经足以满足很多基础层面的需求了。 javalin 还提供了websocket,以及plugins 来支持页面渲染,cors等功能 https://javalin.io/plugins/ 。具体细节可以看看官方文档,https://javalin.io/documentation。有兴趣的可以了解下,以后如果有类似的场景可以考虑是否引入。