程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA編程入門知識 >> 關於Struts2的類型轉換詳解

關於Struts2的類型轉換詳解

編輯:JAVA編程入門知識

一、類型轉換的意義

對於一個智能的MVC框架而言,不可避免的需要實現類型轉換.因為B/S(浏覽器/服務器)結構應用的請求參數是通過浏覽器發送到服務器的,這些參數不可能有豐富的數據類型,因此必須在服務器端完成數據類型的轉換

MVC框架是一個表現層解決方案,理應提供類型轉換的支持,Struts2提供了功能非常強大的類型轉換支持.

二、表現層數據的處理

1、對於web應用而言,表現層主要用於與用戶交互,包括收集用戶輸入數據,向用戶呈現服務器的狀態。因此表現層的數據的流向主要有兩個方向:輸入數據和輸出數據。

2、對於輸入數據:則需要完成由字符串數據向多種類型數據的轉化。程序通常無法自動完成,需要在代碼中手動轉化

3、對於輸出數據:不管是java或是jsp都支持多種數據類型的直接輸出。

4、表現層另外一個數據處理是:數據校驗,分為客戶校驗和服務器端校驗.後邊會重點講解

三、類型轉換

1、HTTP參數都是字符串類型。 保存的數據可能是字符串、數字、布爾、日期時間等或者JavaBean類型。 手工的類型轉換,比如將字符串轉換為日期,通過: 通過request.getParameter方法獲取字符串; 檢查是否為空; 通過DateFormat.parse方法將字符串轉換為Date對象

2、Struts2類型轉換


Struts2內置的類型轉換
String和boolean 完成字符串與布爾值之間的轉換
String和char  往常字符串與字符之間的轉換
String和int、Integer 完成字符串與整型之間的轉換
String和Long 完成字符串與長整型值之間的轉換
String和double、Double 完成字符串與雙精度浮點值的轉換
String和Float 完成字符串和單精度浮點之間的轉換
String和Date 完成字符串和日期類型之間的轉換,日期格式使用格式用戶請求所在Locale的SHORT格式
String和數組 在默認的情況,數組元素是字符串,如果用戶定義類型轉換器,也可以是其它復合數據類型
String和Map、List

Struts2內置的類型轉換
String和boolean 完成字符串與布爾值之間的轉換
String和char  往常字符串與字符之間的轉換
String和int、Integer 完成字符串與整型之間的轉換
String和Long 完成字符串與長整型值之間的轉換
String和double、Double 完成字符串與雙精度浮點值的轉換
String和Float 完成字符串和單精度浮點之間的轉換
String和Date 完成字符串和日期類型之間的轉換,日期格式使用格式用戶請求所在Locale的SHORT格式
String和數組 在默認的情況,數組元素是字符串,如果用戶定義類型轉換器,也可以是其它復合數據類型
String和Map、List

3、內置類型轉換

4、Struts類型轉換的API

Struts2的類型轉換器實際上是基於OGNL實現的,在OGNL項目中有一個ognl.TypeConverter接口,這個接口就是實現類型轉換器必須實現的接口。該接口定義如下:

public interface TypeConverter {
     public Object convertValue(Map arg0, Object arg1, Member arg2, String arg3,
          Object arg4, Class arg5) {
              return null;
}

實現類型轉換器必須實現上面的TypeConverter,不過上面的接口裡的方法過於復雜,所以OGNL項目還提供了一個該接口實現類:ognl.DefaultTypeConverter,通過繼承該類實現自己類型轉換器.該類定義如下:

    public class DefaultTypeConverter extends Object implements TypeConverter{
             public Object convertValue(Map<String,Object> context, Object value, Class toType) {
              }
             ……//其他的方法
     }

ConvertValue方法的作用
該方法完成類型轉換,不過這種類型轉換是雙向的,當需要把字符串轉化對象實例時,通過該方法實現,當把對象實例轉換成字符串時也通過該方法實現。這種轉換是通過toType參數類型是需要轉換的目標類型。所以可以根據toType參數來判斷轉換方向。
ConvertValue方法參數和返回意義
第一個參數:context是類型轉換環境的上下文
第二個參數:value是需要轉換的參數,根據轉換方向的不同value參數的值也是不一樣的。
第三個參數:toType是轉換後的目標類型
該方法的返回值是類型轉換後的值。該值的類型也會隨著轉換的方向的改變而改變。由此可見轉換的convertValue方法接受需要轉換的值,需要轉換的目標類型為參數,然後返回轉換後的目標值
Value為什麼是一個字符串數組?
對於DefaultTypeConverter轉換器而言,它必須考慮到最通用的情形,因此他把所有請求參數都視為字符串數組而不是字符串。相當於getParameterValues()獲取的參數值

四、類型轉換器的實現

1、第一步注冊頁面

2、第二步驟:實現User封裝類

3、第三步驟:實現Action類

5、第五步驟:實現類型轉換器的注冊,注冊方式有以下三種:

 1、注冊局部類型轉換器:局部類型轉換器僅僅對某個Action的屬性其作用
 2、注冊全局類型轉換器:全局類型轉換器對所有Action的特定屬性都會生效
 3、使用JDK1.5的注釋來注冊類型轉換器:通過注冊方式來生成類型轉換器

6、局部類型轉換器注冊
注冊文件名格式:ActionName-conversion.properties:ActionName是需要轉換器生效的Action的類名,後面的-conversion.properties字符串是固定部分
以上文件時典型的properties文件,文件有key-value對組成.文件內容為:propertyName=類型轉換器類
下面是UserAction-conversion.properties文件的內容:
#指定UserAction中的user屬性需要使用redarmy.user.UserConverter類完成類型轉換
user=redarmy.user.UserConverter
注意:以上properties文件一定要與UserAction在同一個包中
即上述案例可采用上面的方式實現局部類型轉換

7、全局類型轉換器
注冊名的文件格式:xwork-conversion.properties文件該文件也是properties文件,其內容也是由”復合類型=對應的類型轉換器類”項組成的。
以下是xwork-conversion.properties文件內容:
     #指定所有redarmy.user.User類的類型轉換器為redarmy.user.UserConverter
     redarmy.user.User=redarmy.user.UserConverter
     注意:xwork-conversion.properties文件必須為class文件夾下即在src下面創建

五、Struts2自定義類型轉換

 在Struts2中提供了StrutsTypeConverter類來簡化自定義類型轉換的設計,這個類有兩個抽象方法需要實現:

     (1) public Object convertFromString(Map context,  String[] values,  Class toClass) ;
          用於String類型數據轉成自定義類型的處理方法
          參數:
             context  --- 與Action有關的上下文信息
             values   --- 從請求中獲取的參數值
             toClass --- 要轉換的目標類型

     (2)  public String convertToString(Map context, Object obj) ;
    用於自定義類型轉換成String
      參數:
         context  --- 與Action有關的上下文信息
         obj --- 自定義類型對象

實例分析:一個日期類型轉換的設計和配置

(1) 設計MyDateTypeConverter,繼承StrutsTypeConverter,覆蓋其中的兩個方法,參考代碼如下:
public Object convertFromString(Map context, String[] values, Class toClass) {
  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  try{
   Date v = sdf.parse(values[0]);
   return v;
  }catch(Exception e){
   e.printStackTrace();
   return new Date();
  }

 }


 public String convertToString(Map context, Object obj) {
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
   Date v = (Date)obj;
   return sdf.format(v);
 }
雖然Struts2默認可支持String和Date的轉換,但僅支持短格式和本地化有關日期格式轉換,不一定符合自己的需要,我們需要實現自己的類型轉換。
(2) 為UserInfo類增加一個birthday屬性,其類型為java.util.Date
public class UserInfo {
 private Integer id;
 private String name;
 private String password;
 private Date birthday;
     ...
}

(3)為UserInfo這個組件配置該類型轉換器
首先,以UserInfo組件的類名為基礎創建一個特性文件,文件命名格式為類名-conversion.properties

     比如UserInfo-conversion.properties

該文件必須和UserInfo組件在同一個包下。

該特性文件內容格式如下:
 birthday=demo.converter.MyDateTypeConverter
 說明:
birthday 為UserInfo組件中java.util.Date類型的屬性名
demo.converter.MyDateTypeConverter為自定義轉換實現類

Strus2框架為我們考慮到這一點,提供了一種簡單的處理方式。

將類型轉換器配置為全局級別,只需編寫一個名為xwork-conversion.properties的特性文件,該文件必須位於/WEB-INF/classes目錄下,內容如下:
            java.util.Date=demo.converter.MyDateTypeConverter

六、自定義類型轉換器

java.util.Date類型的屬性可以接收格式為2009-07-20的請求參數值。但如果我們需要接收格式為20091221的請求參數,我們必須定義類型轉換器,否則struts2無法自動完成類型轉換。

import java.util.Date;
public class HelloWorldAction {
 private Date createtime;

 public Date getCreatetime() {
  return createtime;
 }

 public void setCreatetime(Date createtime) {
  this.createtime = createtime;
 }
}

public class DateConverter extends DefaultTypeConverter {
                @Override  public Object convertValue(Map context, Object value, Class toType) {
 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
 try {
  if(toType == Date.class){//當字符串向Date類型轉換時
   String[] params = (String[]) value;// Request.getParameterValues()
   return dateFormat.parse(params[0]);
  }else if(toType == String.class){//當Date轉換成字符串時
   Date date = (Date) value;
   return dateFormat.format(date);
  }
 } catch (ParseException e) {}
 return null;
 }
}
將上面的類型轉換器注冊為局部類型轉換器:
在Action類所在的包下放置ActionClassName-conversion.properties文件,ActionClassName是Action的類名,後面的-conversion.properties是固定寫法,對於本例而言,文件的名稱應為HelloWorldAction-conversion.properties 。在properties文件中的內容為:
屬性名稱=類型轉換器的全類名
對於本例而言, HelloWorldAction-conversion.properties文件中的內容為:
createtime= cn.csdn.conversion.DateConverter

將上面的類型轉換器注冊為全局類型轉換器:
在WEB-INF/classes下放置xwork-conversion.properties文件 。在properties文件中的內容為:
待轉換的類型=類型轉換器的全類名
對於本例而言, xwork-conversion.properties文件中的內容為:
java.util.Date= cn.csdn.conversion.DateConverter

java.util.Date類型的屬性可以接收格式為2009-07-20的請求參數值。但如果我們需要接收格式為20091221的請求參數,我們必須定義類型轉換器,否則struts2無法自動完成類型轉換。

import java.util.Date;
public class HelloWorldAction {
 private Date createtime;

 public Date getCreatetime() {
  return createtime;
 }

 public void setCreatetime(Date createtime) {
  this.createtime = createtime;
 }
}

public class DateConverter extends DefaultTypeConverter {
                @Override  public Object convertValue(Map context, Object value, Class toType) {
 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
 try {
  if(toType == Date.class){//當字符串向Date類型轉換時
   String[] params = (String[]) value;// Request.getParameterValues()
   return dateFormat.parse(params[0]);
  }else if(toType == String.class){//當Date轉換成字符串時
   Date date = (Date) value;
   return dateFormat.format(date);
  }
 } catch (ParseException e) {}
 return null;
 }
}
將上面的類型轉換器注冊為局部類型轉換器:
在Action類所在的包下放置ActionClassName-conversion.properties文件,ActionClassName是Action的類名,後面的-conversion.properties是固定寫法,對於本例而言,文件的名稱應為HelloWorldAction-conversion.properties 。在properties文件中的內容為:
屬性名稱=類型轉換器的全類名
對於本例而言, HelloWorldAction-conversion.properties文件中的內容為:
createtime= cn.csdn.conversion.DateConverter

將上面的類型轉換器注冊為全局類型轉換器:
在WEB-INF/classes下放置xwork-conversion.properties文件 。在properties文件中的內容為:
待轉換的類型=類型轉換器的全類名
對於本例而言, xwork-conversion.properties文件中的內容為:
java.util.Date= cn.csdnconversion.DateConverter

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved