【Struts2框架】第七節型別轉換-型別轉換原理和自定義型別轉換器例項
1.型別轉換原理
型別轉換是struts攔截器來實現的。
型別轉換的意思是能夠把引數轉換成action裡面所需要的型別。
轉換不了可以使用自己寫的轉換器(但幾乎不用自己寫)。
在struts的傳參過程中,我們已經不知不覺的在使用型別轉換了
例如:
http://localhost:8080/Struts2_upload/type/test?name=jack&age=9
在http傳引數的時候,引數的型別永遠是string型別,但是上述url中,age是int型別。所以發生了型別轉換。
所謂的型別轉換就是把字串轉為特定型別,特定型別轉字串。
特定型別轉字串好轉(寫好toString()就行),但是字串轉為特定型別的話,就要考慮的多了。一般的特定型別struts2都已經解決(在url使用特定的輸入方式),但是某種類的型別,例如Point型別的資料就不太好轉。此時需要定義自定義轉換轉型。
自定義轉換器轉換資料的過程以及原理:
方法1(區域性轉換器,action對應的包下面有轉換檔案):
首先struts2接到引數(一般不是規範寫法,如Point的傳參應該是p.x=1&p.y=2,但是寫成p=1,2,這樣不加轉換器struts2是識別不出來的),假設得到的引數是Point型別的p=5,8。接下來struts2發現並沒有這種東西,轉換不成Point,struts2就會去找action對應的包下面有沒有一個對應的轉換檔案,會去找轉換檔案裡面的成員變數裡有沒有對應的轉換器,如果找到一個,就會嘗試把接收到的引數傳給轉換器“轉換方法”中的形參value,把要轉換的型別傳給toType。最後“轉換方法”執行得到一個結果Object,結果就是一個new出來的Point
方法2(全域性轉換器,src下面有轉換檔案,常用);
轉換檔名稱必須為:xwork-conversion.properties。
如果全域性轉換檔案放在action包外的話,需要指定action引數的具體路徑。
如:java.awt.Point=cn.edu.hpu.converter.MyPointConverter
方法3(註解):
Annotation略
如果遇到非常麻煩的型別轉換,就用:
request.setAttribute();
session
2.幾種型別的輸入
http://localhost:8080/Struts2_upload/type/test?name=jack&age=9
name:jack
age:9
http://localhost:8080/Struts2_upload/type/test?interests=math&interests=english&interests=chinese
[math, english, chinese]
http://localhost:8080/Struts2_upload/type/test?d=1990-8-12%205:32:15
date:90-8-12
1990/08/12 05:32:15
http://localhost:8080/Struts2_upload/type/test?users['a']=usera&users['b']=userb
{b=userb, a=usera}
3.自定義轉換型別器例子
寫一個自定義轉換Point型別引數的轉換器:
struts.xml:
<package name="type" namespace="/type" extends="struts-default">
<action name="test" class="cn.edu.hpu.action.TestAction">
<result>/TypeConversion/test.jsp</result>
</action>
</package>
cn/edu/hpu/action/TestAction.java:
package cn.edu.hpu.action; import java.awt.Point; import java.util.Date; import java.util.List; import java.util.Map; import com.opensymphony.xwork2.ActionSupport; public class TestAction extends ActionSupport { private Point p; public String execute() throws Exception { return super.execute(); } public Point getP() { return p; } public void setP(Point p) { this.p = p; } }
cn/edu/hpu/converter/MyPointConverter.java:
package cn.edu.hpu.converter;
import java.awt.Point;
import java.util.Map;
import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter;
//寫自己的轉換器,繼承DefaultTypeConverter父類
public class MyPointConverter extends DefaultTypeConverter{
@Override
//引數(Object)值傳給value,要轉換的型別傳給toType
public Object convertValue(Object value,Class toType) {
if(toType==Point.class){
Point p=new Point();
String[] strs =(String[])value;
String[] xy=strs[0].split(",");
p.x=Integer.parseInt(xy[0]);
p.y=Integer.parseInt(xy[1]);
return p;
}
if(toType==String.class){
return value.toString();
}
return super.convertValue(value, toType);
}
}
test.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'test.jsp' starting page</title>
</head>
<body>
points:<s:property value="p"/> <br/>
</body>
</html>
重點:
在action所在的包cn/edu/hpu/action/內寫
TestAction-conversion.properties檔案,內容為:
p=cn.edu.hpu.converter.MyPointConverter
輸入:
http://localhost:8080/Struts2_upload/type/test?p=3,4
結果:
points:java.awt.Point[x=3,y=4]
原理:
首先struts2接到引數,假設得到的引數是Point型別的p=5,8。接下來struts2發現並沒有這種東西,轉換不成Point,struts2就會去找action對應的包下面有沒有一個對應的轉換檔案,會去找轉換檔案裡面的成員變數裡有沒有對應的轉換器,如果找到一個,就會嘗試把接收到的引數傳給轉換器“轉換方法”中的形參value,把要轉換的型別傳給toType。最後“轉換方法”執行得到一個結果Object,結果就是一個new出來的Point
4.Point的另一個轉換器
還是以之前的Point轉換為例
<pre name="code" class="java">package cn.edu.hpu.converter;
import java.awt.Point;
import java.util.Map;
import org.apache.struts2.util.StrutsTypeConverter;
import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter;
//寫自己的轉換器2,StrutsTypeConverter繼承自DefaultTypeConverter
//StrutsTypeConverter做了擴充套件和簡化
public class MyPointConverter2 extends StrutsTypeConverter{
@Override
//從String轉成其他型別
public Object convertFromString(Map context, String[] values, Class yoType) {
Point p=new Point();
String[] strs =(String[])values;
String[] xy=strs[0].split(",");
p.x=Integer.parseInt(xy[0]);
p.y=Integer.parseInt(xy[1]);
return p;
}
@Override
//從其他型別轉成String
public String convertToString(Map map, Object o) {
// TODO Auto-generated method stub
return o.toString();
}
}