tinystruct-patterns

tinystruct-patterns

熱門

使用 tinystruct Java 框架進行開發的專業指南。適用於開發 tinystruct 本身或任何基於 tinystruct 的專案,涵蓋建立 Application 類別、@Action 路由對映、單元測試、ActionRegistry、HTTP/CLI 雙模式處理、內建 HTTP 伺服器、事件系統、搭配 Builder/Builders 處理 JSON、透過 AbstractData 進行資料庫持久化、POJO 自動產生、Server-Sent Events (SSE)、檔案上傳以及對外 HTTP 網路請求等情境。

24萬星標
3.6萬分支
更新於 2026/8/3
SKILL.md
唯讀
名稱
tinystruct-patterns
描述

使用 tinystruct Java 框架進行開發的專業指南。適用於開發 tinystruct 本身或任何基於 tinystruct 的專案,涵蓋建立 Application 類別、@Action 路由對映、單元測試、ActionRegistry、HTTP/CLI 雙模式處理、內建 HTTP 伺服器、事件系統、搭配 Builder/Builders 處理 JSON、透過 AbstractData 進行資料庫持久化、POJO 自動產生、Server-Sent Events (SSE)、檔案上傳以及對外 HTTP 網路請求等情境。

tinystruct 開發模式

使用 tinystruct Java 框架建構模組的架構與實作模式。tinystruct 是一款輕量、高效能的框架,將 CLI 與 HTTP 視為同等地位的一等公民,無需 main() 方法且僅需最少配置。

核心原則

CLI 與 HTTP 皆為一等公民。 理想情況下,所有加上 @Action 註解的方法都應能在無需修改的情況下,同時於終端機及瀏覽器中執行。這種「雙模式(dual-mode)」能力是 tinystruct 的核心設計理念。

啟用時機

適用情境

  • 透過繼承 AbstractApplication 來建立新的 Application 模組。
  • 使用 @Action 定義路由與命令列操作。
  • 透過 Context 處理單次請求(per-request)的狀態。
  • 使用原生的 BuilderBuilders 元件進行 JSON 序列化。
  • 透過 AbstractData POJO 處理資料庫持久化。
  • 使用 generate 命令從資料庫資料表自動產生 POJO。
  • 實作 Server-Sent Events (SSE) 進行即時推送。
  • 透過 multipart 資料格式處理檔案上傳。
  • 使用 URLRequestHTTPHandler 發送對外 HTTP 請求。
  • application.properties 中設定資料庫連線或系統參數。
  • 除錯路由衝突(Actions)或 CLI 引數解析問題。

運作原理

tinystruct 框架會將任何加上 @Action 註解的方法視為可供終端機與 Web 環境存取的路由端點。應用程式可透過繼承 AbstractApplication 來建立,此基類提供了如 init() 等核心生命週期 Hook,並可存取請求的 Context

路由對映由 ActionRegistry 負責處理,它會自動將路徑區段(path segments)對映至方法引數並注入相依性。對於純資料服務,應使用原生的 BuilderBuilders 元件來進行 JSON 序列化,以保持零外包相依性(zero-dependency)。資料庫層則使用 AbstractData POJO 搭配 XML 對映檔進行 CRUD 操作,完全不需額外的 ORM 函式庫。

範例程式碼

基礎應用程式 (MyService)

public class MyService extends AbstractApplication {
    @Override
    public void init() {
        this.setTemplateRequired(false); // 針對資料/API 應用程式停用 .view 尋找
    }

    @Override public String version() { return "1.0.0"; }

    @Action("greet")
    public String greet() {
        return "Hello from tinystruct!";
    }

    // 路徑參數:GET /?q=greet/James  或  bin/dispatcher greet/James
    @Action("greet")
    public String greet(String name) {
        return "Hello, " + name + "!";
    }
}

HTTP 模式消歧義 (login)

@Action(value = "login", mode = Mode.HTTP_POST)
public String doLogin(Request<?, ?> request) throws ApplicationException {
    request.getSession().setAttribute("userId", "42");
    return "Logged in";
}

原生 JSON 資料處理 (Builder + Builders)

import org.tinystruct.data.component.Builder;
import org.tinystruct.data.component.Builders;

@Action("api/data")
public String getData() throws ApplicationException {
    Builders dataList = new Builders();
    Builder item = new Builder();
    item.put("id", 1);
    item.put("name", "James");
    dataList.add(item);

    Builder response = new Builder();
    response.put("status", "success");
    response.put("data", dataList);
    return response.toString(); // {"status":"success","data":[{"id":1,"name":"James"}]}
}

SSE (Server-Sent Events)

import org.tinystruct.http.SSEPushManager;

@Action("sse/connect")
public String connect() {
    return "{\"type\":\"connect\",\"message\":\"Connected to SSE\"}";
}

// 推送至指定用戶端
String sessionId = getContext().getId();
Builder msg = new Builder();
msg.put("text", "Hello, user!");
SSEPushManager.getInstance().push(sessionId, msg);

// 廣播給所有人
SSEPushManager.getInstance().broadcast(msg);

檔案上傳

import org.tinystruct.data.FileEntity;

@Action(value = "upload", mode = Mode.HTTP_POST)
public String upload(Request<?, ?> request) throws ApplicationException {
    List<FileEntity> files = request.getAttachments();
    if (files != null) {
        for (FileEntity file : files) {
            System.out.println("Uploaded: " + file.getFilename());
        }
    }
    return "Upload OK";
}

MCP 伺服器與 Tool 整合

tinystruct 自 SDK 版本 1.7.26 起提供對 Model Context Protocol (MCP) 的原生支援。
MCP API(例如 org.tinystruct.mcp.MCPToolorg.tinystruct.mcp.MCPServerorg.tinystruct.mcp.MCPException)已直接包含在核心相依套件中:

<dependency>
    <groupId>org.tinystruct</groupId>
    <artifactId>tinystruct</artifactId>
    <version>1.7.26</version>
</dependency>

資安警告(Prompt Injection 提示詞注入):
Tool 的回傳值會直接送回 AI 模型的上下文視窗(context window)中。在將呼叫端傳入的引數放進 Tool 回傳字串之前,您必須對其進行驗證與清理(sanitize)。若未對輸入進行清理,攻擊者可能注入惡意指令(Prompt Injection)來覆寫模型的行為。請務必驗證引數長度、字元集以及是否為空值(null)。

如何建立 MCP Tool:

  1. 繼承 org.tinystruct.mcp.MCPTool
  2. 使用 @Action 標註操作,並在 arguments 陣列中使用 @Argument 宣告參數。
  3. 接受參數作為顯式的方法引數,且名稱須與 @Argument 中的 key 吻合。(工具引數請使用 getContext().getAttribute(...))。
import org.tinystruct.mcp.MCPTool;
import org.tinystruct.mcp.MCPException;
import org.tinystruct.system.annotation.Action;
import org.tinystruct.system.annotation.Argument;

public class MyCustomTool extends MCPTool {
    public MyCustomTool() {
        super("custom", "A custom tool for demonstrating MCP");
    }

    @Action(
        value = "custom/hello",
        description = "Say hello to someone",
        arguments = {
            @Argument(key = "name", description = "The name to greet", type = "string", optional = false)
        }
    )
    public String hello(String name) throws MCPException {
        // 資安防護:在將 Tool 輸入回傳給模型前進行驗證/清理,
        // 以防止提示詞注入(prompt injection)漏洞。
        if (name == null || name.length() > 50 || !name.matches("^[a-zA-Z0-9 ]+$")) {
            throw new MCPException("Invalid name provided");
        }
        return "Hello, " + name + "!";
    }
}

如何部署 MCP Server:

  1. 繼承 org.tinystruct.mcp.MCPServer
  2. 覆寫 init() 並使用 this.registerTool() 註冊您的工具。框架會自動掃描並對映加有 @Action 的方法。
import org.tinystruct.mcp.MCPServer;

public class MyMCPServer extends MCPServer {
    @Override
    public void init() {
        super.init();
        this.registerTool(new MyCustomTool());
    }

    @Override
    public String version() {
        return "1.0.0";
    }
}

透過分發器(dispatcher)執行伺服器:

bin/dispatcher start --import org.tinystruct.system.HttpServer --import com.example.MyMCPServer

組態設定

設定值皆於 src/main/resources/application.properties 中管理。

# 資料庫
driver=org.h2.Driver
database.url=jdbc:h2:~/mydb
database.user=sa
database.password=

# 伺服器
default.home.page=hello
server.port=8080

# 語系
default.language=en_US

# Session(叢集環境使用 Redis)
# default.session.repository=org.tinystruct.http.RedisSessionRepository
# redis.host=127.0.0.1
# redis.port=6379

在應用程式中存取設定值:

String port = this.getConfiguration("server.port");

地雷與反模式 (Anti-patterns)

徵兆 / 錯誤寫法 正確模式
匯入 com.google.gsoncom.fasterxml.jackson 使用 org.tinystruct.data.component.Builder / Builders
List<Builder> 用於 JSON 陣列 使用 Builders 以避免泛型型別擦除(type erasure)問題。
ApplicationRuntimeException: template not found 針對純 API 應用程式,於 init() 中呼叫 setTemplateRequired(false)
private 方法加上 @Action 註解 Action 必須為 public 才能被框架註冊。
在應用程式中硬編碼 main(String[] args) 所有模組皆應使用 bin/dispatcher 作為進入點。
手動註冊 ActionRegistry 偏好使用 @Action 註解來實現自動偵測與註冊。
執行期找不到 Action 確認類別已透過 --import 載入,或已列於 application.properties 中。
CLI 引數無法讀取 傳入格式為 --key value;透過 getContext().getAttribute("--key") 存取。
兩個方法對映相同路徑,觸發了錯誤方法 設定顯式的 mode(如 HTTP_GETHTTP_POST)來進行消歧義。

最佳實踐

  1. 細粒度應用程式:將邏輯拆分為較小且專一的應用程式,而非寫成單一巨型類別(monolithic class)。
  2. init() 中初始化:利用 init() 進行初始化(如設定、資料庫連線),而非在建構函式中執行。請呼叫 setAction()——請改用 @Action 註解。
  3. 模式感知:善用 @Action 中的 Mode 參數,將敏感操作限制僅允許 CLI 或特定 HTTP 方法執行。
  4. 優先使用 Context 處理可選旗標:對於可選的 CLI 旗標(flags),使用 getContext().getAttribute("--flag") 讀取,而非新增至方法簽章(signature)的參數清單中。
  5. 非同步事件處理:對於事件觸發的高耗時任務,請在事件處理常式內使用 CompletableFuture.runAsync()

技術參考

詳細指南請參閱 references/ 目錄:

參考原始碼檔案 (內部)

  • src/main/java/org/tinystruct/AbstractApplication.java — 包含生命週期 Hook 的核心基類
  • src/main/java/org/tinystruct/system/annotation/Action.java — 註解與 Modes
  • src/main/java/org/tinystruct/application/ActionRegistry.java — 路由引擎
  • src/main/java/org/tinystruct/data/component/Builder.java — JSON 物件序列化器
  • src/main/java/org/tinystruct/data/component/Builders.java — JSON 陣列序列化器
  • src/main/java/org/tinystruct/data/component/AbstractData.java — 具備 CRUD 的 POJO 基類
  • src/main/java/org/tinystruct/data/Mapping.java — XML 對映解析器
  • src/main/java/org/tinystruct/data/tools/MySQLGenerator.java — POJO 產生器參考實作
  • src/main/java/org/tinystruct/data/component/FieldType.java — SQL 至 Java 型別對映
  • src/main/java/org/tinystruct/data/component/Condition.java — 流暢式(Fluent)SQL 查詢建構器
  • src/main/java/org/tinystruct/http/SSEPushManager.java — SSE 連線管理
  • src/test/java/org/tinystruct/application/ActionRegistryTest.java — Registry 測試範例
  • src/test/java/org/tinystruct/system/HttpServerHttpModeTest.java — HTTP 整合測試模式