1.先給一個PointBean,要求對這個bean進行類型轉換
- public class Point {
- private int x;
- private int y;
- public int getX() {
- return x;
- }
- public void setX(int x) {
- this.x = x;
- }
- public int getY() {
- return y;
- }
- public void setY(int y) {
- this.y = y;
- }
- }
2.兩種轉換器, 第一個側重於告訴大家轉換原理, 第二個側重具體實踐
- package edu.hust.common;
- import java.util.Map;
- import ognl.DefaultTypeConverter;
- import edu.hust.bean.Point;
- //較爲底層的一個轉換方法,一般項目中不直接繼承DefaultTypeConverter實現轉換,因爲還有StrutsTypeConverter(繼承自DefaultTypeConverter)進行了更好的封裝。使我們更方便使用。
- //這裏的例子爲了大家理解這個機制。
- public class Converter extends DefaultTypeConverter {
- @SuppressWarnings("unchecked")
- @Override
- public Object convertValue(Map context, Object value, Class toType) {
- /*
- * toType: 當客戶端提交數據時,要求String類型轉換爲自定義類型進行業務處理or存儲(eg:String轉爲Point類);
- * 當客戶端接收數據時,要求自定義類型轉換爲String類型進行顯示輸出。
- * toType起到了類型判斷的作用。
- */
- //String轉換爲Point(Point爲被轉換(toType)類型, 也即目標類型)
- if (Point.class == toType) {
- Point point = new Point();
- //String[] paramValues = ((String)value).split(",");建議這一句用下面兩句去替代。
- /*
- * 爲什麼要將value轉換爲String[]呢?
- * 我們在做表單時可以給2個or多個text的name屬性賦予相同的值(即相同名字)。這樣的話,server端接收name屬性對應的表單屬性時,接收過來的是一個數組(eg: 在Servlet中是用req.getParameterValues()接收這個數組的)。
- * 方法接口爲:public String[] getParameterValues(String name);
- */
- String[] strTxt = (String[]) value;
- String[] paramValues = strTxt[0].split(",");
- int x = Integer.parseInt(paramValues[0]);
- int y = Integer.parseInt(paramValues[1]);
- point.setX(x);
- point.setY(y);
- return point;
- }
- //String爲目標類型(當然不轉換toString()方法會被調用,但我們不希望這樣)
- if (String.class == toType) {
- Point point = (Point)value;
- int x = point.getX();
- int y = point.getY();
- String result = x + "," + y;
- return result;
- }
- return null;
- }
- }
- package edu.hust.common;
- import java.util.Map;
- import org.apache.struts2.util.StrutsTypeConverter;
- import edu.hust.bean.Point;
- public class Converter2 extends StrutsTypeConverter {
- @SuppressWarnings("unchecked")
- @Override
- public Object convertFromString(Map context, String[] values, Class toClass) {
- Point point = new Point();
- String[] paramValues = values[0].split(",");
- int x = Integer.parseInt(paramValues[0]);
- int y = Integer.parseInt(paramValues[1]);
- point.setX(x);
- point.setY(y);
- return point;
- }
- @SuppressWarnings("unchecked")
- @Override
- public String convertToString(Map context, Object o) {
- Point point = (Point)o;
- int x = point.getX();
- int y = point.getY();
- String result = "[x座標:" + x + "],[y座標:" + y +"]";
- return result;
- }
- }
3.action:請詳細閱讀下面這個action的中的註釋
- package edu.hust.action;
- import java.util.Date;
- import com.opensymphony.xwork2.ActionSupport;
- import edu.hust.bean.Point;
- public class ConverterAction extends ActionSupport {
- /*
- * 如何讓ConvertorAction知道Convertor類,並調用其中convertValue()方法進行類型轉換呢?: 需要在ConvertorAction類所在的保內建立一個資源文件:ConvertorAction-conversion.properties.
- *
- * 在這個類中進行setter,getter方法時,ConvertorAction類會自動檢測所在包內有沒有(屬性類型轉換的)資源文件存在。如果存在則優先執行*.properties文件。
- * 在*.properties文件中調用edu.hust.common.Convertor類進行類型轉換後,再執行setter,getter方法。
- *
- * 對於int,Date類型,struts2自動進行轉化。不必我們去寫轉化代碼。但如果我們也手工寫了轉化代碼,則優先使用我們的轉化代碼。如果我們沒有定義轉化,struts2自動轉化。
- * 對於自動轉換的類型,struts2也會進行輸入校驗。對於int,Date類型的,如果我們輸入字符串去提交,struts2自動校驗並根據反射技術,把錯誤打印到對應輸入表單之上(這裏就必須使用struts2的表單,不能使用el進行輸出)。
- * 在這裏我們不推薦使用struts2的自動驗證,其一其功能有限,其二其錯誤輸出信息只是給程序員看的,而會讓使用者一頭霧水。
- * 解決方法:找到自動提示的錯誤信息,將錯誤信息內容覆蓋爲我們希望看到的--通過資源文件。
- *
- * 注:在result頁面顯示的時候,注意用<s:property>標籤顯示和用el顯示的區別(區別很大)。
- *
- * */
- private static final long serialVersionUID = 1L;
- private Point point;
- private int age;
- private String username;
- private Date date;
- public Point getPoint() {
- return point;
- }
- public void setPoint(Point point) {
- this.point = point;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public String getUsername() {
- return username;
- }
- public void setUsername(String username) {
- this.username = username;
- }
- public Date getDate() {
- return date;
- }
- public void setDate(Date date) {
- this.date = date;
- }
- @Override
- public String execute() throws Exception {
- return SUCCESS;
- }
- }
4.類型轉換的局部資源配置文件ConverterAction-conversion.properties
- # 局部的 --> 類型轉換資源文件
- # 這個資源文件的文件名是有規定的:
- # 前半部分:ConvertorAction --> 必須與對應的Action一致。
- # 後半部分:-conversion.properties --> 固定格式,不能修改。
- # 書寫內容:你對ConvertorAction中的哪個屬性進行轉換
- # 對ConvertorAction類中的point對象屬性,用edu.hust.common.Convertor類進行轉換
- # 局部convertion.properties和全局convertion.properties同時定義了對某一類型的轉換時,局部有效、全局無效。
- point = edu.hust.common.Converter
類型轉換的全局資源配置文件xwork-conversion.properties
- # 全局的 --> 類型轉換資源文件
- # 這個資源文件的文件名是固定的,不能修改。
- # 對整個的PointBean進行轉換,無論哪裏用到Point類(即只要調用了PointBean),轉換就會執行。
- # 局部convertion.properties和全局convertion.properties同時定義了對某一類型的轉換時,局部有效、全局無效。
- edu.hust.bean.Point = edu.hust.common.Converter2
5.最後是struts.xml和jsp頁面, 這些和普通struts2無異
- <%@ page contentType="text/html;charset=GBK"%>
- <%@ taglib prefix="s" uri="/struts-tags" %>
- <s:form action="converter" method="post">
- <s:textfield name="point" label="point" />
- <s:textfield name="age" label="age" />
- <s:textfield name="username" label="username" />
- <s:textfield name="date" label="date" />
- <s:submit label="submit" />
- </s:form>
- <!DOCTYPE struts PUBLIC
- "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
- "http://struts.apache.org/dtds/struts-2.0.dtd">
- <struts>
- <package name="struts2" extends="struts-default">
- <action name="converter" class="edu.hust.action.ConverterAction">
- <result>/result.jsp</result>
- </action>
- </package>
- </struts>
- <%@ page contentType="text/html;charset=GBK"%>
- <%@ taglib prefix="s" uri="/struts-tags" %>
- <html>
- <head><title>Login Page</title></head>
- <body bgcolor="#99ffff">
- <!-- 如果使用了*.properties進行類型轉化,你會發現用el輸出和用s標籤輸出效果完全不同, 建議使用s標籤 -->
- <h2>使用s標籤顯示</h2>
- point: <s:property value="point" /><br>
- age: <s:property value="age" /><br>
- username: <s:property value="username" /><br>
- date: <s:property value="date" /><br><br>
- <h2>使用el顯示</h2>
- point: ${point}<br>
- age: ${age}<br>
- username: ${username}<br>
- date: ${date}<br>
- </body>
- </html>