首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Aspire 與 Tomcat 整合:層次資料集 (Hierarchical Data Set) 架構與多格式輸出實作

     編輯:Java 相關知識

前言

Aspire 是一個基於 XML/XSL、J2EE 與關聯式資料庫的 RAD (快速應用開發) 工具,可部署於 Tomcat、WebSphere 等 Servlet 容器。其核心概念層次資料集 (Hierarchical Data Set, HDS) 將關聯式資料轉換為樹狀結構,支援 XML、HTML、Excel、Java 物件等多格式輸出,極大簡化 MVC 架構下 Controller 與 View 的資料傳遞。

層次資料集 (HDS) 核心概念

為什麼需要 HDS?

  • 單一 HDS 可滿足整個頁面所有資料需求 (主檔、明細、子明細...)
  • Controller Servlet 取得 HDS 後直接轉發給 JSP/XSLT,無需多次查詢
  • 天然對應 XML 樹狀結構,轉換為 XML/Excel/報表格式極為自然
  • 支援彙總欄位 (SUM/AVG/COUNT) 於父層顯示子層統計

HDS XML 結構定義

<AspireDataSet>
  <!-- 根層 Key-Value -->
  <key1>val1</key1>
  <key2>val2</key2>
  <!-- 迴圈 = 子資料表 -->
  <loop name="orders">
    <row>
      <orderId>1001</orderId>
      <customer>Acme Corp</customer>
      <!-- 巢狀子迴圈 -->
      <loop name="items">
        <row><itemId>A1</itemId><qty>10</qty></row>
        <row><itemId>B2</itemId><qty>5</qty></row>
      </loop>
    </row>
    <row>...</row>
  </loop>
</AspireDataSet>

loop 對應資料表/子查詢,row 為記錄,支援無限巢狀深度。

Java API: ihds 介面

package com.ai.htmlgen;
public interface ihds extends ILoopForwardIterator {
    ihds getParent();                    // 取得父層 HDS
    IIterator getChildNames();           // 取得子迴圈名稱列表
    ihds getChild(String childName);     // 取得指定子迴圈 HDS
    String getAggregateValue(String key); // 取得彙總值 (SUM/AVG/COUNT)
    IMetaData getMetaData();             // 取得欄位中繼資料
    void close();                        // 釋放資源
}

public interface ILoopForwardIterator {
    String getValue(String key);         // 取得當前行指定欄位值
    void moveToFirst();                  // 移至第一行
    void moveToNext();                   // 移至下一行
    boolean isAtTheEnd();                // 是否已到末尾
}

public interface IMetaData {
    IIterator getIterator();             // 欄位名稱迭代器
    int getColumnCount();                // 欄位數
    int getIndex(String attributeName);  // 欄位索引
}

關鍵特性:非 DOM 實作,記憶體效率高;游標式前向迭代;遞迴巢狀存取。

HDS 定義檔配置 (Aspire Properties)

###################################
# ihdsTest 資料定義
###################################
# 區段 1: 根 HDS 定義
request.ihdsTest.className=com.ai.htmlgen.DBHashTableFormHandler1
request.ihdsTest.loopNames=works

# 區段 2: works 迴圈 (主檔)
request.ihdsTest.works.class_request.className=com.ai.htmlgen.GenericTableHandler6
request.ihdsTest.works.loopNames=childloop1
request.ihdsTest.works.query_request.className=com.ai.data.RowFileReader
request.ihdsTest.works.query_request.filename=aspire:\\samples\\pop-table-tags\\properties\\pop-table.data

# 區段 3: childloop1 迴圈 (明細檔)
request.childloop1.class_request.className=com.ai.htmlgen.GenericTableHandler6
request.childloop1.query_request.className=com.ai.data.RowFileReader
request.childloop1.query_request.filename=aspire:\\samples\\pop-table-tags\\properties\\pop-table.data

核心類別說明

類別角色
DBHashTableFormHandler1根 HDS 建構器,將關聯式資料組裝為層次結構
GenericTableHandler6迴圈處理器,實作 ihds 介面,支援彙總、行數統計
RowFileReader資料來源適配器:平面檔讀取器
DBRequestExecutor2資料來源適配器:SQL 查詢執行器
StoredProcedureExecutor2資料來源適配器:預存程序執行器
XMLReader資料來源適配器:XML 檔案讀取器

資料來源適配器實作 IDataCollection 介面,可自行擴充。

Java 程式碼存取 HDS

Hashtable args = new Hashtable();
args.put("key1".toLowerCase(), "value1");  // 參數鍵值需小寫
IFactory factory = AppObjects.getFactory();
ihds hds = (ihds) factory.getObject("ihdsTest", args);

// 遞迴列印 HDS 結構
public static void staticTransform(ihds data, PrintWriter out) throws TransformException {
    try { writeALoop("MainData", data, out, ""); }
    catch (DataException x) { throw new TransformException("Error", x); }
}

private static void writeALoop(String loopName, ihds data, PrintWriter out, String indent) throws DataException {
    println(out, indent, ">> Writing data for loop: " + loopName);
    // 列印欄位名
    IMetaData m = data.getMetaData();
    IIterator cols = m.getIterator();
    StringBuffer colBuf = new StringBuffer();
    for (cols.moveToFirst(); !cols.isAtTheEnd(); cols.moveToNext()) {
        colBuf.append(cols.getCurrentElement()).append("|");
    }
    println(out, indent, colBuf.toString());
    // 列印資料行
    for (data.moveToFirst(); !data.isAtTheEnd(); data.moveToNext()) {
        StringBuffer rowBuf = new StringBuffer();
        for (cols.moveToFirst(); !cols.isAtTheEnd(); cols.moveToNext()) {
            rowBuf.append(data.getValue((String)cols.getCurrentElement())).append("|");
        }
        println(out, indent, rowBuf.toString());
        // 遞迴處理子迴圈
        IIterator children = data.getChildNames();
        for (children.moveToFirst(); !children.isAtTheEnd(); children.moveToNext()) {
            String childName = (String) children.getCurrentElement();
            writeALoop(childName, data.getChild(childName), out, indent + "\t");
        }
    }
    println(out, indent, ">> Writing data for loop: " + loopName + " is complete");
}

Tomcat 整合:URL 對應與多格式輸出

1. 定義 URL 對應

###################################
# ihdsTestURL: URL 映射
###################################
ihdsTestURL=aspire:\\samples\\ihds-test\\ihds-default-html-template.html
ihdsTestURL.formHandlerName=ihdsTest
request.ihdsTest.form_handler.class_request.className=com.ai.htmlgen.DBHashTableFormHandler1

2. 通用轉換器配置 (aspire.properties)

# XML 輸出
GenericTransform.Classic-xml.classname=com.ai.xml.FormHandlerToXMLTransform
GenericTransform.Object-xml.classname=com.ai.generictransforms.ObjectXMLGenericTransform
# Excel 輸出
GenericTransform.Excel.classname=com.ai.generictransforms.ExcelGenericTransform
# 文字輸出
GenericTransform.Text.classname=com.ai.generictransforms.DebugTextTransform

3. 呼叫 URL 並指定輸出格式

# HTML (預設模板)
https://host:port/webapp/servlet/DisplayServlet?url=ihdsTestURL

# 標準 XML
https://host:port/webapp/servlet/DisplayServlet?url=ihdsTestURL&aspire_output_format=classic-xml

# Excel
https://host:port/webapp/servlet/DisplayServlet?url=ihdsTestURL&aspire_output_format=Excel

# 純文字
https://host:port/webapp/servlet/DisplayServlet?url=ihdsTestURL&aspire_output_format=Text

自訂輸出格式實作範例: ExcelGenericTransform

package com.ai.generictransforms;
public class ExcelGenericTransform extends AHttpGenericTransform implements IFormHandlerTransform {
    private static String s_separator = "\t";
    
    protected String getDerivedHeaders(HttpServletRequest request) {
        return "Content-Type=application/vnd.ms-excel|Content-Disposition=filename=aspire-hierarchical-dataset.xls";
    }
    
    public void transform(ihds data, PrintWriter out) throws TransformException {
        staticTransform(data, out);
    }
    // staticTransform 邏輯同前,以 tab 分隔輸出
}

架構優勢總結

受益角色價值
前端開發者頁面模板只需放置標籤,無需撰寫資料存取邏輯
B2B 整合直接輸出標準 XML,支援系統間資料交換
報表使用者一鍵匯出 Excel,免開發報表程式
Java 開發者取得 ihds 物件直接操作,類似 DOM 但更輕量
學習者免費、輕量、整合 Tomcat+資料庫+XML+XSL,完整 J2EE 學習階梯

現代視角對照

Aspire/HDS 概念對應現代技術:

  • HDS ↔ DTO/VO 樹狀結構、GraphQL 回應、JSON 嵌套物件
  • GenericTransform ↔ MessageBodyWriter (JAX-RS)、HttpMessageConverter (Spring MVC)
  • 資料來源適配器 ↔ Repository/DAO、DataFetcher (GraphQL)
  • URL 格式參數 ↔ Accept Header、格式後綴 (.json/.xml/.xlsx)

雖 Aspire 專案已不活躍,但其「單一資料結構多重表現」的架構思想在現代 API 設計、微服務資料聚合、報表系統中仍具指導意義。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved