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

Struts 2 類型轉換深度解析:內建轉換器、自定義轉換器、註冊機制與最佳實務

     編輯:Java 程式設計入門

為何需要類型轉換

HTTP 參數皆為字串,但 Action 屬性可能是 int、Date、List、自定義物件等。Struts 2 在參數注入前,自動進行字串→目標型別轉換,失敗則收集錯誤到 fieldErrors。

內建支援型別一覽

目標型別說明
基本型別 & 包裝類int/Integer, long/Long, double/Double, float/Float, boolean/Boolean, char/Character
String直接指派
Date依 Locale SHORT 格式(如 yyyy/MM/dd)
陣列元素預設 String,可配合自定義轉換器
Collection (List/Set)元素預設 String
MapKey/Value 預設 String

轉換器架構

  • 核心介面:ognl.TypeConverter(雙向轉換)
  • 便利基類:ognl.DefaultTypeConverter(單一方法 convertValue(Map, Object, Class))
  • Struts 2 進一步封裝:org.apache.struts2.util.StrutsTypeConverter(兩個抽象方法 convertFromString/convertToString)

自定義轉換器三種註冊方式

1. 局部(Action 級) - ActionName-conversion.properties

檔案置於 Action 同包:

# UserAction-conversion.properties
birthday=com.demo.converter.MyDateConverter
user=com.demo.converter.UserConverter

Key 為 Action 屬性名,Value 為轉換器全限定名。

2. 全域(型別級) - xwork-conversion.properties

檔案置於 src/(編譯後在 WEB-INF/classes):

# xwork-conversion.properties
java.util.Date=com.demo.converter.GlobalDateConverter
com.demo.model.User=com.demo.converter.UserConverter

Key 為目標型別全名,對所有 Action 生效。

3. 註解註冊(Struts 2.3+)

@Conversion(type = MyDateConverter.class)
private Date birthday;

需在 struts.xml 啟用:<constant name="struts.enable.ognl.typeConverter" value="true" />。

實戰:自訂日期格式轉換器

繼承 StrutsTypeConverter(推薦)

public class MyDateConverter extends StrutsTypeConverter {
    private static final String PATTERN = "yyyyMMdd";  // 目標格式

    @Override
    public Object convertFromString(Map context, String[] values, Class toClass) {
        if (values == null || values.length == 0) return null;
        SimpleDateFormat sdf = new SimpleDateFormat(PATTERN);
        try {
            return sdf.parse(values[0]);
        } catch (ParseException e) {
            return null;  // 或拋出 ConversionException
        }
    }

    @Override
    public String convertToString(Map context, Object o) {
        if (o instanceof Date) {
            return new SimpleDateFormat("yyyy年MM月dd日").format((Date) o);
        }
        return "";
    }
}

註冊為全域 Date 轉換器

# xwork-conversion.properties
java.util.Date=com.demo.converter.MyDateConverter

如此所有 Date 屬性自動套用 yyyyMMdd 解析、yyyy年MM月dd日 輸出。

完整範例:User 型別轉換器(字串 "id,name" ↔ User 物件)

User.java

public class User {
    private Integer id;
    private String name;
    // getter/setter/toString 省略
}

UserConverter.java

public class UserConverter extends StrutsTypeConverter {
    @Override
    public Object convertFromString(Map context, String[] values, Class toClass) {
        if (values == null || values.length == 0) return null;
        String[] parts = values[0].split(",");
        if (parts.length != 2) return null;
        User u = new User();
        u.setId(Integer.valueOf(parts[0].trim()));
        u.setName(parts[1].trim());
        return u;
    }

    @Override
    public String convertToString(Map context, Object o) {
        if (o instanceof User) {
            User u = (User) o;
            return u.getId() + "," + u.getName();
        }
        return "";
    }
}

Action 註冊(局部)

# UserAction-conversion.properties
user=com.demo.converter.UserConverter

常見坑點與最佳實務

  1. values 為何是 String[]?因 HTTP 允許同名參數多值(如 checkbox),request.getParameterValues() 回傳陣列。
  2. 轉換失敗請拋 ConversionException 或回傳 null,Struts 2 會自動加入 fieldErrors。
  3. 全域轉換器優先級 低於 局部轉換器(Action 級覆蓋全域)。
  4. 集合元素轉換:Struts 2 2.5+ 支援 Element_conversion.properties(元素型別級),或於 xwork-conversion.properties 註冊 java.util.List=com.demo.ListConverter(較少用)。
  5. 大量資料轉換效能:避免在轉換器中做重 IO/DB 操作;若需複雜組裝,建議在 Action prepare() 或 Service 層處理。

除錯技巧

  • 啟用 struts.devMode=true,控制台會印出轉換器呼叫堆疊。
  • 檢查 fieldErrors 是否含 conversionError 關鍵字。
  • 單元測試直接實例化 Converter 呼叫 convertFromString() 驗證邏輯。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved