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

Struts2 請求參數類型轉換全機制詳解:從基礎到複雜對象、集合、JSON

     編輯:Java 綜合教學

Struts2 類型轉換核心機制深度解析:自動裝箱、自定義轉換器、複雜對象圖、集合泛型與 JSON 支援

HTTP 協議無類型概念,所有請求參數到達服務端均為 String 或 String[]。Struts2 通過強大的類型轉換機制,自動將其轉換為 Action 屬性所需的目標類型。本文系統梳理從內置基本類型轉換到自定義轉換器、複雜對象圖、集合泛型、JSON 數據的完整體系,並給出生產級錯誤處理與最佳實踐。

一、內置類型轉換與失敗處理

目標類型轉換行為失敗時默認值
基本類型 int, double, boolean...自動調用對應 valueOf/parseXxx0 / 0.0 / false
包裝類型 Integer, Double, Boolean...同基本類型null
String直接賦值""
Date按 yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss 解析null

錯誤處理機制:Action 實現 ValidationAware(ActionSupport 已實現)時,轉換失敗會:

  1. 將錯誤信息放入 ActionErrors/FieldErrors
  2. 跳過目標方法執行
  3. 返回 result name="input"(未配置則 404)

二、自定義類型轉換器開發


public class MyTypeConverter extends StrutsTypeConverter {
    // String[] → 目標對象
    @Override
    public Object convertFromString(Map context, String[] values, Class toClass) {
        if (Person.class == toClass) {
            Person p = new Person();
            String[] parts = values[0].split(",");
            p.setUserName(parts[0]);
            p.setAge(Integer.parseInt(parts[1]));
            return p;
        }
        if (Address.class == toClass) { ... }
        return null;
    }
    
    // 目標對象 → String(用於表單回顯)
    @Override
    public String convertToString(Map context, Object o) {
        if (o instanceof Person) {
            Person p = (Person) o;
            return p.getUserName() + "," + p.getAge();
        }
        return "";
    }
}

三、轉換器註冊兩種作用域


# 類級別示例:PersonAction-conversion.properties
address=com.example.convert.MyTypeConverter

# 全局級別示例:xwork-conversion.properties
com.example.entity.Person=com.example.convert.MyTypeConverter
com.example.entity.Address=com.example.convert.MyTypeConverter

四、複雜對象圖轉換實戰

場景 1:單個復雜對象,多表單字段映射


// Action 屬性:private Person person;
// JSP
<s:textfield name="person.userName" />
<s:textfield name="person.age" />
// OGNL 自動調用 person.setUserName()/setAge()

場景 2:ModelDriven 模式,棧頂即模型對象


// Action 實現 ModelDriven
// JSP 字段名直接用屬性名
<s:textfield name="userName" />
<s:textfield name="age" />

場景 3:單字段固定格式轉換復雜對象(需自定義轉換器)


// JSP
<s:textfield name="person" />  // 輸入 "Tom,25"
// 轉換器中 values[0] = "Tom,25",split(",") 解析

場景 4:巢狀對象 Person → Address


// 多字段映射
<s:textfield name="address.addressName" />
<s:textfield name="address.location" />

// 單字段固定格式 "Beijing,Chaoyang" → 需在 Person-conversion.properties 註冊 Address 轉換器
<s:textfield name="address" />

五、集合泛型元素轉換

作用域配置文件位置命名規則優先級
類級別Action 同包目錄ActionName-conversion.properties高
全局級別類路徑根目錄xwork-conversion.properties低
Action 結構JSP 字段命名轉換器註冊
List personspersons[0].userName, persons[0].age...Person 轉換器(類級別)
Person addresses: List
(ModelDriven)
addresses[0].addressName...Address 轉換器(在 Person-conversion.properties 中)

關鍵規則:集合元素轉換復用元素類型的轉換器,框架自動根據泛型類型推斷。

六、JSON 數據類型轉換(Struts2 JSON Plugin)


// pom.xml
<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-json-plugin</artifactId>
    <version>2.5.x</version>
</dependency>

// struts.xml
<package name="json" extends="json-default">
    <action name="saveUser" class="com.example.UserAction" method="save">
        <result type="json">
            <param name="root">resultMap</param>
        </result>
    </action>
</package>

// 前端 AJAX
$.post("saveUser", {userName: "Tom", age: 25}, function(data) { ... }, "json");

JSON Plugin 內置反序列化器,自動將 JSON 映射為 Action 屬性對象(支援巢狀、集合),無需手寫轉換器。

七、錯誤信息國際化與前端展示


# ActionName.properties
invalid.fieldvalue.age=年齡必須為數字
invalid.fieldvalue.person=人員信息格式錯誤

# JSP 展示
<s:fielderror fieldName="age" />  // 顯示該字段錯誤
<s:actionerror />                 // 顯示全局錯誤

值棧中錯誤結構:Map>,可通過 OGNL 遍歷:fieldErrors['age'][0]。

八、最佳實踐總結

  1. 優先使用內置轉換,基本類型、日期、常見對象無需配置
  2. 自定義轉換器統一放全局(xwork-conversion.properties),避免分散維護
  3. 表單字段命名遵循 OGNL 路徑:obj.prop、list[0].prop、map['key'].prop
  4. 固定格式單字段轉換復雜對象慎用,維護成本高,優先拆分字段
  5. JSON 交互場景直接用 JSON Plugin,省去手動解析麻煩
  6. 錯誤信息外置到 properties,支援國際化,前端用 <s:fielderror> 統一渲染

掌握 Struts2 類型轉換體系,能讓你從「手動 request.getParameter + 字符串解析」的原始狀態進化到「聲明式自動映射」的高效開發模式,專注於業務邏輯而非參數綁定瑣事。

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