开发中使用Axis2编写WebService的的时候,通常会使用Axis2 code genarator来进行代码的自动生成用以简化客户端的调用。
假设我有以下一个WebService:
public class UserService {
public User getUserByUserName(String userName) {
// do something, and return a User object
return user;
}
}
其中User类的定义如下:
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);
}
}
这时候客户端的调用就会变成如下所示:
GetUserByName method = new GetUserByName();
method.setUserName("somebody");
GetUserByNameResponse response = new UserServiceStub().getUserByName(method);
// 获取返回值
Object object = response.get_return();
大家可能会自然而然的认为object的类型就是User类型,但object的实际类型是com.service.stub.UserServiceStub.User
,并不是我们的想要的User类型。
此时我们就称response.get_return()
的返回对象为衍生对象,它的类型为衍生类型。
衍生类型的定义大致如下:
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
}
从上面可以看到衍生类型其实包含了原始类型的所有的属性和方法,只不过访问属性可能不一样。
所以我们可以利用反射来进行衍生对象与原始对象的转换,代码如下:
// t1是衍生类型的实例
// c2是原始类型
public static <T1, T2> T2 convertObject(T1 t1, Class<T2> c2) throws Exception {
// 创建原始对象实例
T2 t2 = (T2) c2.newInstance();
Class<?> c1 = t1.getClass();
// 获取原始类型的所有属性
Field[] fields = c2.getDeclaredFields();
// 针对于每一个属性,使用getter方法去衍生对象中取值
// 并且使用setter方法赋值给原始对象
for (Field field : fields) {
// 原始对象的属性名与setter方法使用驼峰标识,以便于相互两者相互查找
String camelFieldName = field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
// 获取衍生对象的具体属性的getter方法对象
Method methodT2 = c2.getDeclaredMethod("set" + camelFieldName, field.getType());
// 获取原始对象的具体属性的setter方法对象
Method methodT1 = c1.getDeclaredMethod("get" + camelFieldName);
// 调用原始对象的setter方法,并且将衍生对象的getter的返回值作为参数
methodT2.invoke(t2, methodT1.invoke(t1));
} // for
return t2;
}
方法的性能还是较高的,实际测试在700us左右可以完成转换。
如果想采用其他方式转换,可以参考这篇:
http://blog.csdn.net/10km/article/details/48657959
网友评论