一、前言 筆者一直覺得,學習一個知識點,你首先要明白,這東西是什麼?有什麼用?這樣你才能瞭解。好了,不說廢話。 1.1、類型轉換為何存在?什麼是類型轉換? 在MVC框架中,都是屬於表示層解決方案,都需要負責收集用戶請求的參數,並且將請求參數傳給應用的控制器組件,但是,這裡有一個問題,客戶端提交的請求 ...
一、前言
筆者一直覺得,學習一個知識點,你首先要明白,這東西是什麼?有什麼用?這樣你才能瞭解。好了,不說廢話。
1.1、類型轉換為何存在?什麼是類型轉換?
在MVC框架中,都是屬於表示層解決方案,都需要負責收集用戶請求的參數,並且將請求參數傳給應用的控制器組件,但是,這裡有一個問題,客戶端提交的請求參數都是字元串數據類型,而java這門語言本身就是強類型語言,所以我們需要類型轉換,就是把字元串類型轉化為你所需要的類型。
在MVC框架中,表示層數據處理分為兩個方法:客戶端輸入數據,服務端輸出數據;客戶端輸入數據需要進行類型轉換才能確保我們的數據類型是正確的,服務端輸出數據無需經過類型轉換。
簡單說就是:
在javaweb中,當你在jsp頁面提交一個username到servlet中,你是否在通過request.getParameter("username")去獲取數據;但是
如果是一個Date時間類型呢?你是否要先指定時間的轉換格式,然後再根據request.getParameter("date");獲取數據之後再去轉換呢?但是,你想過沒有?如果是多個頁面請求數據的話,那你每次打getParameter();這個方法,累嗎?你不累,程式都累了。所以,Struts2 為我們提供了一種類型轉換器,只需要編寫固定的操作就能得到你想要的數據,簡單說來,就是把表單的數據賦值給實體類。
1.2、類型轉換器簡單介紹
1.2.1、類型轉換器需要繼承DefaultTypeConverter類,需要重寫該類的convertType方法。
convertType方法的作用:
1、負責對類型的轉換,不過這種轉換是雙向的,我們可以通過判斷數據的類型判斷轉換的方向
2、該方法有三個參數:
context:是類型轉換環境的上下文
value: 是需要轉換的參數(隨轉換方向不同,如果字元串向實例轉換時,它是字元串數組;如果實例字元串轉換時,它是實例)
toType: 是轉換後的目標參數
1.2.2、當然,你也可以繼承StrutsTypeConverter是,它是Struts2為我們簡化的類型轉換器,是DefaultTypeConverter的子類,預設產生兩個方法,更加明確的告訴你你要在哪個方法進行轉換,這樣就不用跟繼承DefaultTypeConverter類一樣,通過convertType方法里的參數toType每次去判斷。繼承StrutsTypeConveter該類比較簡單。這裡兩種繼承都有說到。
二、類型轉換器
2.1、類型轉換器有兩種:局部類型轉換器和全局類型轉換器,就字面上的意思一樣,全局和局部的。
關於類型轉換器的註冊方式有三種:
1、局部類型轉換器僅僅對某個Action起作用
2、全局類型轉換器對所有Action特定類型的屬性都會起作用
3、我們可以通過註解的方式來生成類型轉換器(JDK1.5以上的註解)
2.2、局部類型轉換器:
新建實體類userbean:
package com.TypeConverter; import java.util.Date; public class userbean { private String uname; private String upwd; private int uage; private Date udate; public String getUname() { return uname; } public void setUname(String uname) { this.uname = uname; } public String getUpwd() { return upwd; } public void setUpwd(String upwd) { this.upwd = upwd; } public int getUage() { return uage; } public void setUage(int uage) { this.uage = uage; } public Date getUdate() { return udate; } public void setUdate(Date date) { this.udate = date; } public userbean(){ } public userbean(String uname, String upwd, int uage, Date udate) { this.uname = uname; this.upwd = upwd; this.uage = uage; this.udate = udate; } }userbean
建立jsp視圖:這裡的是Test.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>局部類型轉換器</title> </head> <body> <h2>請輸入您的註冊信息</h2> <form action="user"> <!-- 註意:name的名字必須是userbean1,跟useraction裡面屬性名字一樣 --> <label>用戶名:</label><input type="text" name="userbean1"><br/> <label>密 碼:</label><input type="text" name="userbean1"><br/> <label>年 齡:</label><input type="text" name="userbean1"><br/> <label>生 日:</label><input type="text" name="userbean1"><br/> <input type="submit"> </form> </body> </html>
在struts.xml配置信息。我們只需要配置這個
這裡的<result name="input">是錯誤機制處理程式,就是說當頁面跳轉錯誤或者異常問題的時候,會跳轉到你指定的頁面,這裡筆者是讓其自動跳轉到原來的頁面。
我們可以定義一個局部的錯誤處理消息提示,這裡筆者沒有做,但是可以瞭解下:
新建useraction.properties,放在同級目錄下, 這裡的useraction是值你繼承ActionSupport的類,然後往該文件中寫入: invalid.fieldvalue.屬性名=提示消息(其中屬性名可以是:uname或者upwd等) 當類型轉換錯誤就會跳轉,你可以在頁面上使用JSTL列印,如: <%@ taglib uri="/struts-tags" prefix="s"%> 然後使用<s:fielderror/>該標簽顯示出你的提示消息錯誤消息處理機制
新建useraction類,繼承ActionSupport。
package com.TypeConverter; import com.opensymphony.xwork2.ActionSupport; //使用的是局部的類型轉化器 public class useraction extends ActionSupport { private userbean userbean1; public userbean getUserbean1() { return userbean1; } public void setUserbean1(userbean userbean1) { this.userbean1 = userbean1; } public String execute(){ System.out.println(userbean1.getUname()); System.out.println("useraction"); return SUCCESS; } }
重點來了:我們需要新建類去繼承DefaultTypeConverter,然後重寫裡面的方法。
這裡的類名是TestType
package com.TypeConverter; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Map; import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter; // public class TestType extends DefaultTypeConverter { @Override public Object convertValue(Map<String, Object> context, Object value, Class toType) { //需要將字元串向userbean類型轉換時 if(toType==userbean.class){ //系統的請求參數是一個字元串數組 System.out.println("TestType"); String params[] = (String[]) value; userbean user = new userbean(); user.setUname(params[0]); user.setUpwd(params[1]); user.setUage(Integer.parseInt(params[2])); SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd"); try { user.setUdate(s.parse(params[3])); } catch (ParseException e) { e.printStackTrace(); } return user; }else if(toType==String.class){ userbean user = (userbean) value; System.out.println("--------------------"); return "<"+user.getUname()+">"; } System.out.println("--------------------"); return null; } }
在這裡筆者遇到一點小問題:就是使用
SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd");
s.format(param[3]);
一直報錯誤:Unexpected Exception caught setting 'userbean1' on 'class com.TypeConverter.useraction: Error setting expression 'userbean1' with value ['admin', '123', '20', '1992-1-2', ],直到我把userbean中的udate類型改為Date類型才能夠正常走,並且把s.format換成s.parse(param[3])。疑惑。
筆者測試代碼走的順序:
先走繼承DefaultTypeConverter類的TestType,然後跳轉到useraction類中的execute方法。
註意:我們還需要在建一個文件,告訴程式說,我們要把數據填充到類是哪一個?新建Actionname-conversion.properties
其中-conversion.properties是固定的,需要改變只是Actionname(表示繼承ActionSupport的類,這裡是useraction。對應struts.xml的class)
新建useraction-conversion.properties。放在同級目錄下:
該文件的內容有:
這裡的userbean1是你在useraction中實例化的名字。
後面的TestType是你繼承DefaultTypeConverter類的名字。這裡是TestType
代碼運行結果如下:
Test.jsp界面
target.jsp界面效果:
target.jsp的代碼:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>類型轉化器輸出結果</title> </head> <body> 用戶名:${userbean1.uname }<br/> 密碼:${userbean1.upwd }<br/> 年齡:${userbean1.uage }<br/> 生日:${userbean1.udate }<br/> </body> </html>target.jsp的代碼
2.3、全局類型轉換
2.3.1、對指定的類型的全部屬性有效。基本操作一樣,只是有一點不同,properties文件放的位置和名字不同。
新建jsp頁面,頁面名:Test1.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>使用全局的類型轉換器</title> </head> <body> <h2>使用全局的類型轉換器</h2> <form action="Stubean"> <label>用戶名:</label><input type="text" name="stu"><br/> <label>年 齡:</label><input type="text" name="stu"><br/> <input type="submit"> </form> </body> </html>Test1.jsp
新建實體類StuBean:
package com.TypeConverter.global; public class StuBean { private String uname; private int uage; public String getUname() { return uname; } public void setUname(String uname) { this.uname = uname; } public int getUage() { return uage; } public void setUage(int uage) { this.uage = uage; } }StuBean
配置struts.xml
新建StuAction類繼承ActionSupport
package com.TypeConverter.global; import com.opensymphony.xwork2.ActionSupport; //使用全局的類型轉換器 //執行順序:類型轉換器——>execute public class StuAction extends ActionSupport { private StuBean stu; public StuBean getStu() { return stu; } public void setStu(StuBean stu) { this.stu = stu; } public String execute(){ System.out.println("StuAction"); System.out.println(stu.getUname()); return SUCCESS; } }StuAction
新建GlobalTypeConverter類繼承StrutsTypeConverter,這裡的StrutsTypeConverter是簡化類型轉換器,它是DefaultTypeConverter的子類。以下是代碼:
package com.TypeConverter.global; import java.util.Map; import org.apache.struts2.util.StrutsTypeConverter; public class GlobalTypeConverter extends StrutsTypeConverter { //轉化為javabean對象 @Override public Object convertFromString(Map arg0, String[] arg1, Class arg2) { System.out.println("Global..."); StuBean stu = new StuBean(); stu.setUname(arg1[0]); stu.setUage(Integer.parseInt(arg1[1])); return stu; } //轉化為String對象 @Override public String convertToString(Map arg0, Object arg1) { StuBean s = (StuBean)arg1; return s.getUname()+"!!"; } }GlobalTypeConverter
註意:全局與局部不同的地方在於properties文件名和放的位置不同,全局的文件名為:xwork-conversion.properties
位置在:
放在classes之下,有些沒有classes文件,需要自己創建。
內容為:
前面的是該StuBean實體類的路徑,後面的是繼承StrutsTypeConverter類的類型轉換器
如果要設置錯誤處理消息的話,我們可以添加一行代碼,當頁面出錯的時候提示,這裡筆者沒有做,但是可以瞭解,添加代碼為:
xwork.default.invalid.fieldvalue=提示消息
顯示效果上面有介紹。如果你需要的話可以使用。
代碼運行結果為:
Test1.jsp界面
target1.jsp界面
有誰能介紹一個錄製操作的軟體,謝謝。
以上就是Struts2 類型轉換器的基本知識,有不足的請下方留言。謝謝。