1. 程式人生 > >【Struts2框架】第七節型別轉換-型別轉換原理和自定義型別轉換器例項

【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();
	}
	
}