Struts2中Action接收參數的方法主要有以下三種:


Struts2中Action接收參數的方法主要有以下三種: 

1.使用Action的屬性接收參數(最原始的方式): 
    a.定義:在Action類中定義屬性,創建get和set方法; 
    b.接收:通過屬性接收參數,如:userName; 
    c.發送:使用屬性名傳遞參數,如:user1!add?userName=jim; 
2.使用DomainModel接收參數: 
    a.定義:定義Model類,在Action中定義Model類的對象(不需要new),創建該對象的get和set方法; 
    b.接收:通過對象的屬性接收參數,如:user.getUserName(); 
    c.發送:使用對象的屬性傳遞參數,如:user2!add?user.userName=mike; 
3.使用ModelDriven接收參數(現在用的比較多的方式): 
    a.定義:Action實現ModelDriven泛型接口,定義Model類的對象(必須new),通過getModel方法返回該對象; 
    b.接收:通過對象的屬性接收參數,如:user.getUserName(); 
    c.發送:直接使用屬性名傳遞參數,如:user2!add?userName=tom 

詳細如下:

一 、Action接收請求參數

struts2內部提供三種請求參數封裝機制

1)      Action 本身作為model對象,通過成員setter封裝(使用與成員少的)

 

[java]  view plain  copy
 
 print?
  1. <form action="${pageContext.request.contextPath }/regist1.action" method="post">  
  2.     用戶名 <input type="text" name="username" /><br/>  
  3.     密碼<input type="password" name="password"/><br/>  
  4.     年齡 <input type="text" name="age" /><br/>  
  5.     <input type="submit" value="注冊" />  
  6. </form>  
  7.   
  8. public class RegistAction1 extends ActionSupport {  
  9.     提交的有什么參數就設置什么字段,並寫好setter方法  
  10.     private String username;  
  11.     private String password;  
  12.     private int age;  
  13.     public void setUsername(String username) {  
  14.         this.username = username;  
  15.     }  
  16.     public void setPassword(String password) {  
  17.         this.password = password;  
  18.     }  
  19.     public void setAge(int age) {  
  20.         this.age = age;  
  21.     }  
  22. }  

 

 

注:通過以上特性就能清楚,struts2的action是多例的,每個用戶有每個用戶的參數,每個參數封裝到一        組javabean中,也就是說每次請求都會創建 struts2的Action 對象。

 

         2)創建獨立model對象,頁面通過ognl表達式封裝

[java]  view plain  copy
 
 print?
  1. <form action="${pageContext.request.contextPath }/regist2.action" method="post">  
  2.     用戶名 <input type="text" name="user.username" /><br/>  
  3.     密碼<input type="password" name="user.password"/><br/>  
  4.     年齡 <input type="text" name="user.age" /><br/>  
  5.     <input type="submit" value="注冊" />  
  6. </form>     
  7. * 頁面中使用ognl寫法 name="user.username"  底層就會執行 Action的setUser() --- > setUsername();  
  8. 在action中的寫法  
  9. public class RegistAction2 extends ActionSupport {  
  10.     private User user;持有對象  
  11.     public void setUser(User user) {  
  12.         this.user = user;  
  13.     }  
  14. // 必須提供get方法 ----- 如果不提供只能封裝一個屬性,下次再封裝第二個屬性的時候又是一個新的user  
  15.     public User getUser() {  
  16.         return this.user;  
  17.     }  
  18. }  
  19. 單獨創建一個user的domain  
  20. public class User {  
  21.     private String username;  
  22.     private String password;  
  23.     private int age;  
  24.     ...  
  25. }  

 

         3)使用ModelDriven接口,對請求數據進行封裝

頁面可以直接寫屬性名稱

[java]  view plain  copy
 
 print?
  1. <form action="${pageContext.request.contextPath }/regist3.action" method="post">  
  2.     用戶名 <input type="text" name="username" /><br/>  
  3.     密碼<input type="password" name="password"/><br/>  
  4.     年齡 <input type="text" name="age" /><br/>  
  5.     <input type="submit" value="注冊" />  
  6. </form>  
  7.   
  8. public class RegistAction3 extends ActionSupport  implements ModelDriven<User> {  
  9.     private User user = new User(); // 必須手動new,不然就出現空指針異常  
  10.     @Override  
  11.     public User getModel() {  
  12.         return user;  
  13.     }  
  14. }  
  15. 單獨創建一個user的domain  
  16. public class User {  
  17.     private String username;  
  18.     private String password;  
  19.     private int age;  
  20. }  

 

原理:發起請求后, struts2 會調用 getModel().setUsername()、 getModel().setPassword()因此必須手動 對model進行初始化

結論:三種參數封裝方式,在開發中主要使用第三種

           第一種只適用於請求參數非常少的情況的封裝,第二種更加靈活,支持一個表單數據封裝到不同model對象,第三種封裝方式,只能支持一個model對象。

 

二、 向集合元素屬性中封裝數據 (封裝參數第二種寫法,ognl 靈活寫法)

Collection(List、Set) 、 Map 

[java]  view plain  copy
 
 print?
  1. 1、 Collection 接收  
  2. <form>  
  3.     第一個員工 姓名 <input type="text" name="employees[0].name" /><br/>  
  4.     第一個員工工資 <input type="text" name="employees[0].salary" /><br/>  
  5.     第二個員工 姓名 <input type="text" name="employees[1].name" /><br/>  
  6.     第二個員工工資 <input type="text" name="employees[1].salary" /><br/>  
  7.     <input type="submit" value="提交" />  
  8. </form>  
  9.   
  10. public class EmployeeAction extends ActionSupport {  
  11.     // 接收多個 Employee信息,定義集合  
  12.     private Collection<Employee> employees;  
  13.     提供set、get方法  
  14.     public Collection<Employee> getEmployees() {  
  15.         return employees;  
  16.     }  
  17.     public void setEmployees(Collection<Employee> employees) {  
  18.         this.employees = employees;  
  19.     }  
  20. }  
  21.   
  22. 2、 Map 接收  
  23. <form action="${pageContext.request.contextPath }/employee2.action" method="post">  
  24.     第一個員工 姓名 <input type="text" name="employees['first'].name" /><br/>  
  25.     第一個員工工資 <input type="text" name="employees['first'].salary" /><br/>  
  26.     第二個員工 姓名 <input type="text" name="employees['second'].name" /><br/>  
  27.     第二個員工工資 <input type="text" name="employees['second'].salary" /><br/>  
  28.     <input type="submit" value="提交" />  
  29. </form>  
  30.   
  31. public class EmployeeAction2 extends ActionSupport {  
  32.     private Map<String, Employee> employees;  
  33.     public Map<String, Employee> getEmployees() {  
  34.         return employees;  
  35.     }  
  36.     public void setEmployees(Map<String, Employee> employees) {  
  37.         this.employees = employees;  
  38.     }  
  39. }  

 

Struts2內建類型轉換器

對於大部分常用類型,開發者根本無需創建自己的轉換器,Struts2內置了常見數據類型多種轉換器

•    boolean 和 Boolean

•    char和 Character

•    int 和 Integer

•    long 和 Long

•    float 和 Float

•    double 和 Double

•    Date 可以接收 yyyy-MM-dd格式字符串

•    數組  可以將多個同名參數,轉換到數組中

•    集合  支持將數據保存到 List或者 Map 集合

客戶端請求過來的數據都是字符串,struts2可以判斷你的model中相對於的字段是什么類型的,再幫你將字符串轉換成什么類型的。但是有時我們的需求類型並不止這些,因此這時候就要自定義轉換器了。

內建類型無法轉換時就會拋出這樣的異常:java.lang.NoSuchMethodException:

         Struts2 類型轉換器實際上都是基於OGNL實現的,在OGNL項目中,有一個TypeConverter接口,自定        義類型轉換器必須實現ongl.TypeConverter

備注:TypeConverter接口提供convertValue方法,此方法要傳入6個參數,DefaultTypeConverter實現了              TypeConverter接口,覆蓋了convertValue方法,需要傳入3個參數,在struts2內部提供                                 StrutsTypeConverter 繼承DefaultTypeConverter,將 convertValue 拆分為兩個方法:

         convertFromString(java.util.Mapcontext, java.lang.String[] values, java.lang.Class toClass)

         convertToString(java.util.Map context,java.lang.Object o)

自定義類型轉換器,繼承 DefaultTypeConverter ,覆蓋 convertValue

  在convertValue方法中有兩層含義,第一種 String到目標類型,第二種目標類型到 String 

[java]  view plain  copy
 
 print?
  1. 1、 自定義類型轉換器   
  2.     例:public class DateConverter extends DefaultTypeConverter {  
  3.                 @Override  public Object convertValue(Map context, Object value, Class toType) {  
  4.     SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");  
  5.     try {   
  6.         if(toType == Date.class){//當字符串向Date類型轉換時  
  7.             String[] params = (String[]) value;// Request.getParameterValues()   
  8.             return dateFormat.parse(params[0]);  
  9.         }else if(toType == String.class){//當Date轉換成字符串時  
  10.             Date date = (Date) value;  
  11.             return dateFormat.format(date);  
  12.         }  
  13.     } catch (ParseException e) {}  
  14.     return null;  
  15.     }  
  16. }  

 

2、 在struts2 框架中注冊類型轉換器

第一種 局部類型轉換器,只針對當前Action有效

在Action類所在的包下放置ActionClassName-conversion.properties文件

         屬性名稱=類型轉換器的全類名

 

第二種 全局類型轉換器,對所有Action都有效

在src下放置xwork-conversion.properties文件

         待轉換的類型=類型轉換器的全類名

 

3、 在類型轉換過程中發生異常,自動跳轉到 input 結果頁面  

<interceptorname="conversionError"class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/>負責當發生類型轉換錯誤時,將轉換錯誤信息 保存到 fielderror 中

 

在jsp中 通過struts2 提供標簽 <s:fielderror /> 查看類型轉換錯誤信息

在查看之前需要導入標簽庫<%@tagliburi="/struts-tags" prefix="s" %> 

<s:fielderror/>

 

自定義錯誤信息?? 需要國際化信息文件

在Action所在包中,創建 ActionName.properties,在局部資源文件中配置提示信息 :invalid.fieldvalue.屬性名= 錯誤信息

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM