最近了解到一款轻量级的web 开发框架,刚好最近需要开发一些简单,但是时间比较紧的web应用,就萌生出使用该框架的想法。
1.开发环境
JDK版本:17
Javalin版本:6.1.3
参考资料Javalin
2.使用方式
在pom 文件内导入依赖
<dependency>
<groupId>io.javalin</groupId>
<artifactId>javalin</artifactId>
<version>6.1.3</version>
</dependency>
如果需要使用到日志输出,需要导入以下依赖
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.10</version>
</dependency>
如果需要接口返回json格式,需要导入以下依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.16.1</version>
</dependency>
2.1.启动web 服务
通过以下一行的代码,即可以启动一个端口为7070的web服务
var app = Javalin.create().start(7070);
2.2.定义Api接口
启动服务后,可以获取到Javalin对象 app,可以通过app设置对应的接口
//定义一个get 请求
app.get("/test", ctx -> {
Map<String, String> map = new HashMap<>();
map.put("resultCode", "1");
map.put("resultMsg", "get : hello world");
ctx.json(map);
});
//定义一个post 请求
app.post("/test", ctx -> {
Map<String, String> map = new HashMap<>();
map.put("resultCode", "1");
map.put("resultMsg", "post : hello world");
ctx.json(map);
});
//定义一个put 请求
app.put("/test", ctx -> {
Map<String, String> map = new HashMap<>();
map.put("resultCode", "1");
map.put("resultMsg", "put : hello world");
ctx.json(map);
});
//定义一个delete 请求
app.delete("/test", ctx -> {
Map<String, String> map = new HashMap<>();
map.put("resultCode", "1");
map.put("resultMsg", "delete : hello world");
ctx.json(map);
});
2.3.获取接口的请求参数
你可以通过ctx对象获取到请求的参数,该ctx在 get/post/put/delete中使用方法一样
获取地址栏上的?传参
app.get("/hello", ctx -> {
//获取在地址栏上通过?传递的某个参数?name=aaa
String name = ctx.queryParam("name");
//获取在地址栏上通过?传递的所有参数?name=aaa&age=18
Map<String, List<String>> queryParamMap = ctx.queryParamMap();
Map<String, String> map = new HashMap<>();
map.put("resultCode", "1");
map.put("resultMsg", "get : hello world");
ctx.json(map);
});
获取路径参数
app.get("/hello/{name}", ctx -> {
//获取在路径传递的某个参数/hello/{name}
String name = ctx.pathParam("name");
//获取在路径传递的所有参数/hello/{name}
Map<String, String> pathParamMap = ctx.pathParamMap();
Map<String, String> map = new HashMap<>();
map.put("resultCode", "1");
map.put("resultMsg", "get : hello world");
ctx.json(map);
});
获取在request body内传递参数
app.post("/hello", ctx -> {
User user = ctx.bodyAsClass(User.class);
ctx.json(user);
});
//定义一个测试用的User对象
class User {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
2.4.Api请求拦截
//调用请求之前,无论该路径是否存在(包括404),都会进入拦截
app.before("/test/*", ctx -> ctx.result("before "+ctx.url()));
//调用请求之后,无论该路径是否存在(包括404),都会进入拦截
app.after("/test/*", ctx -> ctx.result("after "+ctx.url()));
//调用请求之前,该路径存在(没有触发404),会进入拦截
app.beforeMatched("/test/*", ctx -> ctx.result("beforeMatched "+ctx.url()));
//调用请求之后,该路径存在(没有触发404),会进入拦截
app.afterMatched("/test/*", ctx -> ctx.result("afterMatched "+ctx.url()));
可以通过ctx获取到请求的参数,详细可参考2.3
2.5.异常拦截
app.exception(Exception.class, (e, ctx) -> ctx.result("exception : " + e.getMessage()));
可以通过ctx获取到请求的参数,详细可参考2.3
2.6.路由分组
路由分组可以通过在创建Javalin对象的时候通过router.apiBuilder进行配置
var app = Javalin.create(config -> {
config.staticFiles.add("template");
config.router.apiBuilder(() -> {
path("/test", () -> {
get("/hello", ctx -> ctx.result("Hello World"));
before("/*", ctx -> System.out.println("Before" + ctx.url()));
});
});
})
.start(7070);
通过path方法指定父级路由,在path 方法内的所有请求和拦截器都会以父级路由的路径作为开头
例如上面的例子,/hello定义在path /test下,则请求的路径为/test/hello
拦截器/*定义在path /test下,则拦截/test/下的所有请求