RESTX 簡介

REST
Remote
0
09:49 AM · Dec 01 ,2025

1. 概述

在本教程中,我們將對輕量級 Java REST 框架 RESTX 進行遊覽。

2. 功能

使用 RESTX 框架構建 RESTful API 非常容易。它包含了我們從 REST 框架中期望的所有默認設置,例如服務和消費 JSON、查詢和路徑參數、路由和過濾機制、使用統計信息和監控。

RESTX 還附帶了一個直觀的管理員 Web 控制枱和命令行安裝程序,方便快速啓動。

它還獲得 Apache License 2 的許可,並由開發人員社區維護。RESTX 的最小 Java 要求是 JDK 7。

3. 配置

RESTX 附帶一個便捷的 shell/命令行應用,可快速啓動 Java 項目。

在繼續之前,我們需要先安裝該應用。詳細的安裝説明請參考 這裏

4. 安裝核心插件

現在,是時候安裝核心插件,以便從shell本身創建應用程序。

在RESTX shell中,請運行以下命令:

shell install

它會提示我們選擇要安裝的插件。我們需要選擇指向io.restx:restx-core-shell的序號。 安裝完成後,shell會自動重啓。

5. Shell App 啓動

使用 RESTX shell,非常方便地啓動新的應用程序。它提供基於嚮導的引導。

我們首先在 shell 上執行以下命令:

app new

此命令將觸發嚮導。然後我們可以選擇使用默認選項或根據我們的要求進行更改:

shell app bootstrap

由於我們選擇生成一個pom.xml,該項目可以輕鬆導入到任何標準的 Java IDE。

在某些情況下,我們可能需要調整IDE 設置

下一步將是構建項目:

mvn clean install -DskipTests

一旦構建成功,我們就可以從 IDE 中作為 Java 應用程序運行 AppServer。 這將在端口 8080 上啓動服務器,帶有管理控制枱。

我們可以瀏覽到 http://127.0.0.1:8080/api/@/ui 並查看基本 UI。

/@/ 開頭且使用 RESTX 的路由用於管理控制枱,這是一個預留的路徑。

要登錄管理控制枱,我們可以使用默認用户名“admin“ 和我們在創建應用程序時提供的密碼。

在玩轉控制枱之前,讓我們探索代碼並瞭解嚮導生成的內容。

6. RESTX 資源

路由定義在 <em>main_package>.rest.HelloResource 類中:

@Component
@RestxResource
public class HelloResource {
    @GET("/message")
    @RolesAllowed(Roles.HELLO_ROLE)
    public Message sayHello() {
        return new Message().setMessage(String.format("hello %s, it's %s", 
          RestxSession.current().getPrincipal().get().getName(),
          DateTime.now().toString("HH:mm:ss")));
    }
}

可以立即看出,RESTX 使用了默認的 J2EE 註解來處理安全性以及 REST 綁定。 大部分情況下,它使用自己的註解來處理依賴注入。

RESTX 還支持了許多合理的默認值,用於將方法參數映射到請求。

此外,還有 <em>@RestxResource</em> 註解,它聲明該類為 RESTX 識別的資源。

基本路徑在 <em>src/main/webapp/WEB-INF/web.xml</em> 中添加。 在我們的例子中,它是 <em>/api</em>,因此我們可以向 <em>http://localhost:8080/api/message</em> 發送 GET 請求,前提是進行了適當的身份驗證。

Message 類只是一個 Java Bean,RESTX 將其序列化為 JSON。

我們通過指定 <em>RolesAllowed</em> 註解以及 <em>HELLO_ROLE</em> (由啓動器生成的) 來控制用户訪問。

7. 模塊類

如前所述,RESTX 使用 J2EE 標準的依賴注入註解,如 @Named,並在需要時自行創建,很可能借鑑了 Dagger 框架中 @Module 和 @Provides 的用法。

它使用這些註解來創建應用程序的主模塊,該模塊中定義了管理員密碼:

@Module
public class AppModule {
    
    @Provides
    public SignatureKey signatureKey() {
        return new SignatureKey("restx-demo -44749418370 restx-demo 801f-4116-48f2-906b"
            .getBytes(Charsets.UTF_8));
    }

    @Provides
    @Named("restx.admin.password")
    public String restxAdminPassword() {
        return "1234";
    }

    @Provides
    public ConfigSupplier appConfigSupplier(ConfigLoader configLoader) {
        return configLoader.fromResource("restx/demo/settings");
    } 
   
    // 其他提供方法來創建組件 
}

@Module 定義了一個可以定義其他組件的類,類似於 Dagger 中的@Module 或 Spring 中的@Configuration

@Provides 編程方式地暴露一個組件,類似於 Dagger 中的@Provides 或 Spring 中的@Bean

最後,@Named 註解用於指示所產生的組件的名稱。

AppModule 還提供了一個SignatureKey,用於對客户端發送的內容進行簽名。 在創建樣本應用程序的會話時,例如,這將設置一個帶有配置鍵簽名的 cookie:

HTTP/1.1 200 OK
...
Set-Cookie: RestxSessionSignature-restx-demo="ySfv8FejvizMMvruGlK3K2hwdb8="; RestxSession-restx-demo="..."
...

更多信息請查看 RESTX 組件工廠/依賴注入文檔

8. Launcher 類

最後,AppServer 類用於在嵌入式 Jetty 服務器上以標準 Java 應用的方式運行應用程序:

public class AppServer {
    public static final String WEB_INF_LOCATION = "src/main/webapp/WEB-INF/web.xml";
    public static final String WEB_APP_LOCATION = "src/main/webapp";

    public static void main(String[] args) throws Exception {
        int port = Integer.valueOf(Optional.fromNullable(System.getenv("PORT")).or("8080"));
        WebServer server = 
            new Jetty8WebServer(WEB_INF_LOCATION, WEB_APP_LOCATION, port, "0.0.0.0");
        System.setProperty("restx.mode", System.getProperty("restx.mode", "dev"));
        System.setProperty("restx.app.package", "restx.demo");
        server.startAndAwait();
    }
}

在此,在開發階段使用 dev 模式以啓用諸如自動編譯等功能,從而縮短開發反饋循環。

我們可以將應用程序打包為 war 文件(Web 存檔)以便在獨立 J2EE Web 容器中部署。

在下一部分中,我們將瞭解如何測試該應用程序。

9. 集成測試使用規範

RESTX 的強大功能之一是“規範”(specs) 的概念。一個示例 規範 看起來像這樣:

title: should admin say hello
given:
  - time: 2013-08-28T01:18:00.822+02:00
wts:
  - when: |
      GET hello?who=xavier
    then: |
      {"message":"hello xavier, it's 01:18:00"}

測試是用 給、當、然後 結構在 YAML 文件中編寫的,該文件基本上定義了 API 如何響應(然後)一個特定請求()在系統當前狀態下()。

HelloResourceSpecTest 類在 src/test/resources 中將觸發上述規範中的測試:

@RunWith(RestxSpecTestsRunner.class)
@FindSpecsIn("specs/hello")
public class HelloResourceSpecTest {}

RestxSpecTestsRunner 類是一個自定義 JUnit 運行器。它包含自定義 JUnit 規則,用於:

  • 設置嵌入式服務器
  • 準備系統狀態(根據規範中的 部分)
  • 發出指定請求,以及
  • 驗證預期響應

@FindSpecsIn 註解指向測試應運行的規範文件路徑。

規範有助於編寫集成測試並提供 API 文檔中的示例。 規範也對 模擬 HTTP 請求和記錄請求/響應對 有用。

10. 手動測試

我們還可以通過HTTP進行手動測試。首先,我們需要登錄,為此,需要在RESTX控制枱中對管理員密碼進行哈希:

hash md5 <clear-text-password>

然後,我們可以將它傳遞給/sessions端點:

curl -b u1 -c u1 -X POST -H "Content-Type: application/json" 
  -d '{"principal":{"name":"admin","passwordHash":"1d528266b85cf052803a57288"}}'
  http://localhost:8080/api/sessions

(注意,Windows 用户需要下載 curl)

現在,如果我們使用會話作為/message請求的一部分:

curl -b u1 "http://localhost:8080/api/message?who=restx"

然後,我們將會得到類似這樣的內容:

{"message" : "hello admin, it's 09:56:51"}

11. 探索管理控制枱

管理控制枱提供有用的資源來控制應用程序。

讓我們通過瀏覽到http://127.0.0.1:8080/admin/@/ui來查看關鍵功能。

11.1. API 文檔

API 文檔部分列出了所有可用的路由,包括所有選項:

admin api docs

我們可以點擊單個路由並嘗試在控制枱中對其進行測試:

admin api docs 2

11.2. 監控

JVM 指標部分顯示了應用程序指標,包括活動會話、內存使用情況和線程 dump:

admin monitoring

應用程序指標中,我們有默認監控的兩種主要類別:

  • BUILD 對應於應用程序組件的實例化
  • HTTP 對應於 RESTX 處理的 HTTP 請求

11.3. 統計信息

RESTX 允許用户選擇收集和共享應用程序的匿名統計信息,以便向 RESTX 社區提供信息。我們可以輕鬆通過排除 restx-stats-admin 模塊來選擇退出。

統計報告包括底層操作系統和 JVM 版本:

admin stats

因為這個頁面顯示了敏感信息,請務必查看其配置選項

除此之外,管理控制枱還可以幫助我們:

  • 檢查服務器日誌 (Logs)
  • 查看遇到的錯誤 (Errors)
  • 檢查環境變量 (Config)

12. 授權

RESTX 端點默認已啓用安全保護。這意味着對於任何端點:

@GET("/greetings/{who}")
public Message sayHello(String who) {
    return new Message(who);
}

如果未進行身份驗證,則默認返回一個 401 錯誤。

要使端點公開,我們需要使用 @PermitAll 註解,該註解可以在方法或類級別使用:

@PermitAll 
@GET("/greetings/{who}")
public Message sayHello(String who) {
    return new Message(who);
}

請注意,在類級別,所有方法都是公開的。

此外,框架還允許使用 @RolesAllowed 註解指定用户角色:

@RolesAllowed("admin")
@GET("/greetings/{who}")
public Message sayHello(String who) {
    return new Message(who);
}

通過此註解,RESTX 將驗證已身份驗證的用户是否也具有 admin 角色分配。如果未具有 admin 角色且已身份驗證的用户嘗試訪問端點,則應用程序將返回一個 403 錯誤,而不是 401 錯誤。

默認情況下,用户角色和憑據存儲在文件系統中,在單獨的文件中。

因此,包含加密密碼的用户 ID 存儲在 /data/credentials.json 文件下:

{
    "user1": "$2a$10$iZluUbCseDOvKnoe",
    "user2": "$2a$10$oym3Swr7pScdiCXu"
}

並且,用户角色定義在 /data/users.json 文件中:

[
    {"name":"user1", "roles": ["hello"]},
    {"name":"user2", "roles": []}
]

在示例應用程序中,文件通過 AppModuleFileBasedUserRepository 類加載:

new FileBasedUserRepository<>(StdUser.class, mapper, 
  new StdUser("admin", ImmutableSet.<String> of("*")), 
  Paths.get("data/users.json"), Paths.get("data/credentials.json"), true)

StdUser 類持有用户對象。它可以是自定義用户類,但需要可序列化為 JSON。

當然,我們可以使用不同的 UserRepository 實現,例如一個連接到數據庫的實現。

13. 結論

本教程概述了輕量級基於Java的RESTX框架。

該框架仍在開發中,可能存在一些不完善之處。請查閲 官方文檔 以獲取更多詳細信息。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.