1. 概述
Jooby 是一个基于主流 NIO Web 服务器构建的可扩展、高性能微 Web 框架。它设计简洁且高度模块化,专为现代 Web 架构量身打造,同时支持 JavaScript 和 Kotlin 开发。
默认情况下,Jooby 对 Netty、Jetty 和 Undertow 提供开箱即用的支持。
本文将带你了解 Jooby 的项目结构,并手把手教你构建一个简单的 Web 应用。
2. 应用架构
典型的 Jooby 应用结构如下:
├── public
| └── welcome.html
├── conf
| ├── application.conf
| └── logback.xml
└── src
| ├── main
| | └── java
| | └── com
| | └── baeldung
| | └── jooby
| | └── App.java
| └── test
| └── java
| └── com
| └── baeldung
| └── jooby
| └── AppTest.java
├── pom.xml
关键点说明:
public
目录:存放静态资源(CSS/JS/HTML 等)conf
目录:存放配置文件(如logback.xml
或application.conf
)
3. Maven 依赖
通过以下依赖即可快速构建 Jooby 应用:
<dependency>
<groupId>io.jooby</groupId>
<artifactId>jooby-netty</artifactId>
<version>2.16.1</version>
</dependency>
若需改用 Jetty 或 Undertow:
<!-- Jetty -->
<dependency>
<groupId>io.jooby</groupId>
<artifactId>jooby-jetty</artifactId>
<version>2.16.1</version>
</dependency>
<!-- Undertow -->
<dependency>
<groupId>io.jooby</groupId>
<artifactId>jooby-undertow</artifactId>
<version>2.16.1</version>
</dependency>
最新版本可查阅 Maven 中央仓库
4. 构建应用
4.1. 启动服务器
启动嵌入式服务器只需以下代码:
public class App extends Jooby {
public static void main(String[] args) {
run(args, App::new);
}
}
默认运行在 8080 端口。自定义端口和 HTTPS 端口配置如下:
{
setServerOptions(new ServerOptions()
.setPort(8080)
.setSecurePort(8433));
}
4.2. 实现路由
Jooby 的路由定义极其简洁。例如创建 /login
接口:
{
get("/login", ctx -> "Hello from Baeldung");
}
处理其他 HTTP 方法(POST/PUT 等)同样简单:
{
post("/save", ctx -> {
String userId = ctx.query("id").value();
return userId;
});
}
✅ 参数类型支持:header、cookie、path、query、form、multipart、session、flash,均提供统一类型安全的 API。
路径参数处理示例:
// 两种写法等价
get("/user/{id}", ctx -> "Hello user : " + ctx.path("id").value());
get("/user/:id", ctx -> "Hello user: " + ctx.path("id").value());
固定前缀路径参数(如 uid:
):
get("/uid:{id}", ctx -> "Hello User with id : uid = " + ctx.path("id").value());
4.3. MVC 模式控制器
企业级开发中,Jooby 提供类似 Spring MVC 的 MVC API。例如处理 /hello
接口:
@Path("/submit")
public class PostController {
@POST
public String hello() {
return "Submit Baeldung";
}
}
其他 HTTP 方法通过 @POST
、@PUT
、@DELETE
等注解实现。
4.4. 处理静态资源
将静态文件(HTML/CSS/JS/图片等)放入 public
目录后,通过以下方式映射:
{
assets("/employee", "public/form.html");
}
4.5. 表单处理
Jooby 的 Request
接口自动处理表单对象,无需手动类型转换。以员工信息提交为例:
定义数据模型:
public class Employee { String id; String name; String email; // 标准构造器、getter/setter }
创建表单页面:
<form enctype="application/x-www-form-urlencoded" action="/submitForm" method="post"> <label>Employee id:</label><br> <input name="id"/><br> <label>Name:</label><br> <input name="name"/><br> <label>Email:</label><br> <input name="email"/><br><br> <input type="submit" value="Submit"/> </form>
处理表单提交:
post("/submitForm", ctx -> { Employee employee = ctx.path(Employee.class); // 业务逻辑... return "employee data saved successfully"; });
⚠️ 关键点:表单必须声明 enctype="application/x-www-form-urlencoded"
才能启用动态绑定。
4.6. 会话管理
Jooby 提供三种会话实现:内存会话、签名会话、带存储的内存会话。
内存会话
{
get("/sessionInMemory", ctx -> {
Session session = ctx.session();
session.put("token", "value");
return session.get("token").value();
});
}
签名会话(无状态)
{
String secret = "super secret token";
setSessionStore(SessionStore.signed(secret));
get("/signedSession", ctx -> {
Session session = ctx.session();
session.put("token", "value");
return session.get("token").value();
});
}
存储扩展
除内置内存存储外,还支持:
- Caffeine:基于 Caffeine 缓存的内存存储
- JWT:JSON Web Token 存储
以 Redis 为例:
添加依赖:
<dependency> <groupId>io.jooby</groupId> <artifactId>jooby-redis</artifactId> <version>2.16.1</version> </dependency>
配置 Redis 会话:
{ install(new RedisModule("redis")); setSessionStore(new RedisSessionStore(require(RedisClient.class))); get("/redisSession", ctx -> { Session session = ctx.session(); session.put("token", "value"); return session.get("token"); }); }
在 application.conf
中配置 Redis 地址:
redis = "redis://localhost:6379"
更多示例参考 Jooby 官方文档
5. 测试
单元测试
添加测试依赖:
<dependency>
<groupId>io.jooby</groupId>
<artifactId>jooby-test</artifactId>
<version>2.16.1</version>
</dependency>
使用 MockRouter
测试默认接口:
public class AppUnitTest {
@Test
public void given_defaultUrl_with_mockrouter_expect_fixedString() {
MockRouter router = new MockRouter(new App());
assertEquals("Hello World!", router.get("/").value());
}
}
集成测试
基于 JUnit 5 的集成测试示例:
@JoobyTest(value = App.class, port = 8080)
public class AppLiveTest {
static OkHttpClient client = new OkHttpClient();
@Test
public void given_defaultUrl_expect_fixedString() {
Request request = new Request.Builder()
.url("http://localhost:8080")
.build();
try (Response response = client.newCall(request).execute()) {
assertEquals("Hello World!", response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
}
关键说明:
@JoobyTest
自动管理应用启停- 默认端口 8911,可通过
port()
方法修改 - 注解支持类级别和方法级别使用
更多测试示例见 官方文档
6. 总结
本文系统介绍了 Jooby 框架的核心功能与实战技巧。作为一款现代化的微框架,Jooby 在保持简洁性的同时提供了强大的扩展能力,特别适合构建高性能 Web 服务。
完整源码请查阅 GitHub 仓库。