開(kāi)發(fā)中使用Axis2編寫(xiě)WebService的的時(shí)候记劝,通常會(huì)使用Axis2 code genarator來(lái)進(jìn)行代碼的自動(dòng)生成用以簡(jiǎn)化客戶(hù)端的調(diào)用。
假設(shè)我有以下一個(gè)WebService:
public class UserService {
public User getUserByUserName(String userName) {
// do something, and return a User object
return user;
}
}
其中User類(lèi)的定義如下:
public class User {
private char[] address;
private Integer age;
private String userName;
public char[] getAddress() {
return address;
}
public Integer getAge() {
return age;
}
public String getUserName() {
return userName;
}
public void setAddress(char[] address) {
this.address = address;
}
public void setAge(Integer age) {
this.age = age;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String toString() {
return "userName: " + userName + "age: " + age + "address: " + new String(address);
}
}
這時(shí)候客戶(hù)端的調(diào)用就會(huì)變成如下所示:
GetUserByName method = new GetUserByName();
method.setUserName("somebody");
GetUserByNameResponse response = new UserServiceStub().getUserByName(method);
// 獲取返回值
Object object = response.get_return();
大家可能會(huì)自然而然的認(rèn)為object的類(lèi)型就是User類(lèi)型盖矫,但object的實(shí)際類(lèi)型是com.service.stub.UserServiceStub.User
丽惭,并不是我們的想要的User類(lèi)型。
此時(shí)我們就稱(chēng)response.get_return()
的返回對(duì)象為衍生對(duì)象炼彪,它的類(lèi)型為衍生類(lèi)型吐根。
衍生類(lèi)型的定義大致如下:
public class User implements org.apache.axis2.databinding.ADBBean {
protected java.lang.String userName;
// other fields and their getters, setters
public static UserDTO parse(javax.xml.stream.XMLStreamReader reader) throws java.lang.Exception
}
從上面可以看到衍生類(lèi)型其實(shí)包含了原始類(lèi)型的所有的屬性和方法,只不過(guò)訪問(wèn)屬性可能不一樣辐马。
所以我們可以利用反射來(lái)進(jìn)行衍生對(duì)象與原始對(duì)象的轉(zhuǎn)換拷橘,代碼如下:
// t1是衍生類(lèi)型的實(shí)例
// c2是原始類(lèi)型
public static <T1, T2> T2 convertObject(T1 t1, Class<T2> c2) throws Exception {
// 創(chuàng)建原始對(duì)象實(shí)例
T2 t2 = (T2) c2.newInstance();
Class<?> c1 = t1.getClass();
// 獲取原始類(lèi)型的所有屬性
Field[] fields = c2.getDeclaredFields();
// 針對(duì)于每一個(gè)屬性,使用getter方法去衍生對(duì)象中取值
// 并且使用setter方法賦值給原始對(duì)象
for (Field field : fields) {
// 原始對(duì)象的屬性名與setter方法使用駝峰標(biāo)識(shí)喜爷,以便于相互兩者相互查找
String camelFieldName = field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
// 獲取衍生對(duì)象的具體屬性的getter方法對(duì)象
Method methodT2 = c2.getDeclaredMethod("set" + camelFieldName, field.getType());
// 獲取原始對(duì)象的具體屬性的setter方法對(duì)象
Method methodT1 = c1.getDeclaredMethod("get" + camelFieldName);
// 調(diào)用原始對(duì)象的setter方法冗疮,并且將衍生對(duì)象的getter的返回值作為參數(shù)
methodT2.invoke(t2, methodT1.invoke(t1));
} // for
return t2;
}
方法的性能還是較高的,實(shí)際測(cè)試在700us左右可以完成轉(zhuǎn)換檩帐。
如果想采用其他方式轉(zhuǎn)換术幔,可以參考這篇:
http://blog.csdn.net/10km/article/details/48657959