1. 簡介
Javalin 是為 Java 和 Kotlin 編寫的輕量級 Web 框架。它基於 Jetty Web 服務器構建,因此具有高性能。Javalin 的設計靈感來源於 koa.js,這意味着它從頭開始構建,旨在簡單易懂且易於擴展。
在本教程中,我們將逐步構建一個基本的 REST 微服務,使用這個輕量級框架。
2. 添加依賴項
為了創建一個基本應用程序,我們只需要一個依賴項——Javalin 本身:
<dependency>
<groupId>io.javalin</groupId>
<artifactId>javalin</artifactId>
<version>1.6.1</version>
</dependency>當前版本可以在 這裏找到。
3. 設置 Javalin
Javalin 使構建基本應用程序變得容易。我們首先將定義我們的主類並設置一個簡單的“Hello World”應用程序。
讓我們在我們的基本包中創建一個新文件,名為 JavalinApp.java。
在文件中,我們創建一個主方法並添加以下內容以設置基本應用程序:
Javalin app = Javalin.create()
.port(7000)
.start();
app.get("/hello", ctx -> ctx.html("Hello, Javalin!"));我們正在創建一個新的 Javalin 實例,使其監聽 7000 端口,然後啓動應用程序。
我們還設置了第一個端點,監聽一個 GET 請求,位於 /hello 端點。
讓我們運行此應用程序,並訪問 http://localhost:7000/hello 以查看結果。
4. 創建 UserController
“Hello World” 示例對於介紹主題非常有用,但對於實際應用來説並不具價值。讓我們現在來看一下 Javalin 的一個更實際的應用場景。
首先,我們需要創建一個模型,用於表示我們正在處理的對象。我們首先在項目的根目錄下創建一個名為 user 的包。
然後,我們添加一個新的 User 類:
public class User {
public final int id;
public final String name;
// constructors
}此外,我們需要設置我們的數據訪問對象(DAO)。在本例中,我們將使用內存對象來存儲我們的用户。
我們在<em>user</em> 包中創建了一個名為<em>UserDao.java</em> 的新類:
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());
}
}將我們的 DAO 設計為單例模式,使其在示例中更容易使用。我們還可以將其聲明為主類中的靜態成員,或者如果需要,從像 Guice 這樣的庫中進行依賴注入。
最後,我們想要創建一個控制器類。 Javalin 允許我們在聲明路由處理程序時具有很大的靈活性,因此這只是定義路由處理程序的一種方式。
我們創建一個名為 UserController.java 的新類,位於 user 包中:
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);
} else {
ctx.html("Not Found");
}
};
}通過將處理程序聲明為靜態的,我們確保控制器本身不持有任何狀態。但是,在更復雜的應用程序中,我們可能需要請求之間存儲狀態,這時就需要移除靜態修飾符。
請注意,與靜態方法相比,單元測試更困難,因此如果我們希望進行這種級別的測試,則需要使用非靜態方法。
5. 添加路由
我們現在已經有多種方法可以從我們的模型中獲取數據。最後的步驟是使用 REST 端點暴露這些數據。我們需要在我們的主應用程序中註冊兩個新的路由。
讓我們將它們添加到我們的主應用程序類中:
app.get("/users", UserController.fetchAllUsernames);
app.get("/users/:id", UserController.fetchById);在編譯並運行應用程序後,我們可以向這些新的端點發送請求。調用 http://localhost:7000/users 將列出所有用户,調用 http://localhost:7000/users/0 將獲取 ID 為 0 的單個 User JSON 對象。我們現在擁有一個微服務,可以檢索 User 數據。
6. 擴展路由
檢索數據是大多數微服務的關鍵任務。
然而,我們也需要能夠將數據存儲在我們的存儲庫中。Javalin 提供完整的路徑處理程序集,用於構建服務。
我們之前看到一個 GET 的示例,但 PATCH, POST, DELETE, PUT 也是可用的。
此外,如果我們將 Jackson 作為依賴項包含進來,我們就可以自動將 JSON 請求主體解析為我們的模型類。例如:
app.post("/") { ctx ->
User user = ctx.bodyAsClass(User.class);
}這將會允許我們從請求體中獲取 JSON <em User 對象並將其轉換為 <em User 模型對象。
7. 結論
我們可以將這些技術結合起來,構建我們的微服務。
在本文中,我們學習瞭如何設置 Javalin 並構建一個簡單的應用程序。我們還討論瞭如何使用不同的 HTTP 方法類型,以便客户端與我們的服務進行交互。
要查看 Javalin 的更高級示例,請務必查看 文檔。