1. 简介

Javalin 是一个轻量级的 Web 框架,专为 Java 和 Kotlin 设计。它底层基于 Jetty 构建,性能表现非常出色。Javalin 的设计灵感源自 koa.js,从零开始就追求简洁易懂,API 设计直观,上手成本极低。

本文将带你一步步使用 Javalin 构建一个基础的 REST 风格微服务。适合想快速搭建轻量后端接口的同学,踩坑少、开发快,简单粗暴有效。


2. 添加依赖

要启动一个基本的 Javalin 应用,你只需要引入一个核心依赖:

<dependency>
    <groupId>io.javalin</groupId>
    <artifactId>javalin</artifactId>
    <version>1.6.1</version>
</dependency>

✅ 建议使用最新稳定版,可在 Maven Central 查询当前版本。

⚠️ 注意:虽然版本号看起来不高,但 Javalin 社区活跃,API 稳定,无需担心“老版本”问题。


3. 初始化 Javalin 应用

Javalin 的初始化非常简洁,几行代码就能跑起来。

创建主类 JavalinApp.java,写入以下内容:

Javalin app = Javalin.create()
  .port(7000)
  .start();

app.get("/hello", ctx -> ctx.html("Hello, Javalin!"));

解释一下关键点:

  • Javalin.create():创建应用实例
  • .port(7000):监听 7000 端口
  • .start():启动内嵌的 Jetty 服务器
  • app.get(...):注册一个 GET 类型的接口

启动后访问 http://localhost:7000/hello,就能看到返回内容。

✅ 这是最小可运行单元,适合做原型验证或内部工具。


4. 实现 UserController

“Hello World” 只是热身,接下来我们搞点实际的:用户管理。

4.1 定义 User 模型

user 包下创建 User 类:

public class User {
    public final int id;
    public final String name;

    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }
}

⚠️ 注意:这里使用 public final 字段是为了配合 Jackson 自动序列化,省去 getter。生产环境建议用 private + getter,但 demo 中简化处理。

4.2 实现 UserDao(数据访问层)

我们用内存存储模拟数据库,实际项目可替换为 JPA、MyBatis 等。

class UserDao {

    private List<User> users = Arrays.asList(
      new User(0, "Steve Rogers"),
      new User(1, "Tony Stark"),
      new User(2, "Carol Danvers")
    );

    private static UserDao userDao = null;

    private UserDao() {
    }

    static UserDao instance() {
        if (userDao == null) {
            userDao = new UserDao();
        }
        return userDao;
    }

    Optional<User> getUserById(int id) {
        return users.stream()
          .filter(u -> u.id == id)
          .findAny();
    }

    Iterable<String> getAllUsernames() {
        return users.stream()
          .map(user -> user.name)
          .collect(Collectors.toList());
    }
}

✅ 使用单例模式简化示例,避免依赖注入复杂化。
❌ 但注意:静态单例不利于单元测试和扩展,真实项目建议用 Spring 或 Guice 管理生命周期。

4.3 创建 UserController

这是接口逻辑的核心。我们将 Handler 定义为静态方法,保持无状态:

public class UserController {
    public static Handler fetchAllUsernames = ctx -> {
        UserDao dao = UserDao.instance();
        Iterable<String> allUsers = dao.getAllUsernames();
        ctx.json(allUsers);
    };

    public static Handler fetchById = ctx -> {
        int id = Integer.parseInt(Objects.requireNonNull(ctx.param("id")));
        UserDao dao = UserDao.instance();
        Optional<User> user = dao.getUserById(id);
        if (user.isPresent()) {
            ctx.json(user.get());
        } else {
            ctx.status(404).html("Not Found");
        }
    };
}

关键点说明:

  • ctx.param("id"):获取路径参数 /users/:id 中的 id
  • ctx.json(...):自动序列化对象为 JSON 响应
  • ctx.status(404):设置状态码,更符合 REST 规范

5. 注册接口(Routes)

现在把 Controller 中的 Handler 挂载到路由上:

app.get("/users", UserController.fetchAllUsernames);
app.get("/users/:id", UserController.fetchById);

启动服务后测试:

  • GET http://localhost:7000/users
    返回:["Steve Rogers", "Tony Stark", "Carol Danvers"]

  • GET http://localhost:7000/users/1
    返回:{"id":1,"name":"Tony Stark"}

  • GET http://localhost:7000/users/999
    返回 404 和 "Not Found" 文本

至此,一个支持查询的 REST 微服务已成型。


6. 扩展接口功能

光有读取不够,我们还需要支持增删改。

Javalin 支持所有标准 HTTP 方法:

  • app.get() → 查询
  • app.post() → 创建
  • app.put() → 全量更新
  • app.patch() → 部分更新
  • app.delete() → 删除

6.1 自动解析 JSON 请求体

添加 Jackson 依赖(Javalin 默认已包含,无需额外引入):

app.post("/users", ctx -> {
    User user = ctx.bodyAsClass(User.class);
    // 保存逻辑...
    ctx.status(201).json(user);
});

bodyAsClass 会自动将请求体反序列化为指定类,前提是字段名匹配且有构造函数。

6.2 示例:添加用户

private static AtomicInteger idCounter = new AtomicInteger(3);

app.post("/users", ctx -> {
    User newUser = ctx.bodyAsClass(User.class);
    int newId = idCounter.getAndIncrement();
    User savedUser = new User(newId, newUser.name);
    // 实际应加入 users 列表
    ctx.status(201).json(savedUser);
});

📌 提示:内存存储不支持持久化,仅用于演示。真实场景需对接数据库。


7. 总结

通过本文,你应该掌握了:

  • ✅ 如何快速初始化 Javalin 应用
  • ✅ 使用静态 Handler 组织 Controller 逻辑
  • ✅ 路由注册与参数解析
  • ✅ JSON 自动序列化/反序列化
  • ✅ 构建完整的 RESTful 接口集

Javalin 的优势在于轻量、无侵入、低学习成本,特别适合:

  • 内部工具系统
  • 快速原型开发
  • 学习 REST 设计
  • 替代 Spring Boot 做极简服务

📌 官方文档非常完善:https://javalin.io/documentation
📌 示例代码已托管 GitHub:https://github.com/example/javalin-demo

如果你厌倦了 Spring 的臃肿配置,不妨试试 Javalin,说不定就成了你新的“生产力神器”。


原始标题:Creating REST Microservices with Javalin