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

Struts 2.0 Action 詳解:從 POJO 到結果類型的完整指南

     編輯:Java 相關知識

Struts 2 將 Action 從重型的繼承體系釋放為輕量級 POJO,配合攔截器鏈與結果類型系統,構建出極具彈性的控制器層。本文對比 Struts 1.x 差異,詳細示範 Action 開發、多方法分派、結果類型擴展(Velocity/FreeMarker)、表單資料綁定、巢狀屬性存取,以及 Servlet API 獲取的 IoC 與非 IoC 兩種模式。

一、Struts 1.x vs 2.0 Action 模型對比

特性Struts 1.xStruts 2.0
類型限制必須繼承 org.apache.struts.action.Action無需繼承/實現任何介面(建議繼承 ActionSupport)
表單資料封裝於 ActionForm (FormBean)直接作為 Action 屬性,Getter/Setter 存取
執行緒安全單例共享,需同步每請求一實例,天然線程安全
方法分派依賴 DispatchAction 等子類原生支援 method 屬性與 !methodName 語法

二、基礎 Action 開發範例

1. Action 類

package tutorial;
import com.opensymphony.xwork2.ActionSupport;
import java.text.DateFormat;
import java.util.Date;

public class HelloWorld extends ActionSupport {
    private String message;

    public String getMessage() { return message; }

    @Override
    public String execute() {
        message = "Hello World, Now is " + DateFormat.getInstance().format(new Date());
        return SUCCESS; // 來自 Action 介面常數
    }
}

2. JSP 視圖

<%@ taglib prefix="s" uri="/struts-tags" %>
<html><body>
<h2><s:property value="message" /></h2>
</body></html>

3. struts.xml 配置

<package name="ActionDemo" extends="struts-default">
    <action name="HelloWorld" class="tutorial.HelloWorld">
        <result>/HelloWorld.jsp</result>
    </action>
</package>

訪問 HelloWorld.action 即可看到動態時間輸出。

三、多方法分派:突破單一 execute

在 Action 中新增業務方法:

public String aliasAction() {
    message = "自訂 Action 呼叫方法";
    return SUCCESS;
}

兩種映射方式:

  1. XML 顯式指定:
    <action name="AliasHelloWorld" class="tutorial.HelloWorld" method="aliasAction">
        <result>/HelloWorld.jsp</result>
    </action>
  2. URL 動態分派:HelloWorld!aliasAction.action(含驚嘆號)。

兩者效果等價,靈活適配 REST 風格或傳統映射。

四、結果類型擴展:不只是 Forward

result 的 type 屬性支援多種視圖技術:

  • dispatcher(預設):JSP 轉發
  • velocity:Velocity 模板
  • freemarker:FreeMarker 模板
  • jasper:JasperReports
  • xslt:XSLT 轉換
  • 自訂類型:實作 Result 介面

Velocity 範例

<action name="VMHelloWorld" class="tutorial.HelloWorld">
    <result type="velocity">/HelloWorld.vm</result>
</action>
# HelloWorld.vm
<html><body>
<h2>Message rendered in Velocity: $message</h2>
</body></html>

需額外引入 velocity-1.4.jar、velocity-tools-view-1.2.jar 等依賴。

五、表單資料綁定:POJO 化輸入

1. 扁平屬性綁定

// Login.java
public class Login extends ActionSupport {
    private String name, password, message;
    // Getter/Setter 略
    @Override public String execute() {
        if ("max".equals(name) && "secret".equals(password))
            message = "Welcome, " + name;
        else
            message = "Invalid user or password";
        return SUCCESS;
    }
}
<!-- Login.jsp -->
<s:form action="Login" method="POST">
    <s:textfield name="name" label="User name"/>
    <s:password name="password" label="Password"/>
    <s:submit value="Submit"/>
</s:form>

表單 name 與 Action 屬性同名,自動注入。

2. 巢狀屬性綁定(領域模型驅動)

// User.java
public class User { private String name, password; /* Getter/Setter */ }

// LoginX.java
public class LoginX extends ActionSupport {
    private User user;
    private String message;
    public User getUser() { return user; }
    public void setUser(User user) { this.user = user; }
    @Override public String execute() {
        if ("max".equals(user.getName()) && "secret".equals(user.getPassword()))
            message = "Welcome, " + user.getName();
        else
            message = "Invalid user or password";
        return SUCCESS;
    }
}
<!-- LoginX.jsp -->
<s:textfield name="user.name" label="User name"/>
<s:password name="user.password" label="Password"/>

OGNL 表達式 user.name 自動實例化 User 並設值,極大簡化分層架構中 Action 到 Domain Object 的資料流轉。

六、Servlet API 獲取:非 IoC vs IoC

方式核心類代碼範例優缺點
非 IoCServletActionContext
HttpServletRequest req = ServletActionContext.getRequest();
HttpSession session = req.getSession();
簡單直接,但耦合靜態工具類,單元測試較難
IoC實作 ServletRequestAware 等介面
public class IoCServlet extends ActionSupport
    implements SessionAware, ServletRequestAware, ServletResponseAware {
    private Map session; // Map 代表 Session
    private HttpServletRequest request;
    public void setSession(Map session) { this.session = session; }
    public void setServletRequest(HttpServletRequest req) { this.request = req; }
    // ...
}
容器注入,利於測試與解耦,符合 Struts 2 設計哲學

兩種方式均可在 execute() 中存取 request、response、session,IoC 方式更優雅。

七、ActionSupport 實作的介面清單

繼承 ActionSupport 即獲得:

  • Action(結果常數)
  • Validateable、ValidationAware(驗證支援)
  • LocaleProvider、TextProvider(國際化)
  • Serializable、Cloneable
  • ContinuableObject(WebFlow 整合)

這使 Action 具備驗證、國際化、類型轉換等開箱即用能力。

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