import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.XmlFriendlyReplacer;
import com.thoughtworks.xstream.io.xml.XppDriver;
/**
*Module: XML_OBJTOXML.java
*Description: 报文的封装
*Company:
*Author: pantp
*Date: Feb 23, 2012
*/
/*
* 用到的主要知识如下:
* 1.BeanInfo/Introspector/PropertyDescriptor/Method的使用
* 2.XStream.jar包相关类及方法的使用
* 3.javabean
*/
/*
假设报文格式如下:
<user_info>
<username>testuser</username>
<password>password</password>
</user_info>
*/
/**
* 定义一个javabean,实际开发中javabean是一个单独的类,这里为了方便就放在了一个类中
* 实际开发中是先定义报文格式和字段,然后根据定义的报文建立javabean以及属性字段名称
*/
class UserInfo {
// 此处的属性名称就是最后发送报文中的字段名称
// 这几个类的使用时javabean的属性的类型不能有多种(如:String和int不能共存、但是int和long可以共存),否则后面会报异常
return username;
}
public void setUsername
(String username
) {
this.username = username;
}
return password;
}
public void setPassword
(String password
) {
this.password = password;
}
}
// =========================================【javabean定义完成】============================================================
public class XML_OBJTOXML {
private static UserInfo userInfo = null;
/**
* 整合4个方法,提供一个程序的访问的接口
*
* @return
* @throws Exception
*/
/*
* 1.放值到map对象中
*/
putValue(parameter);
/*
* 2.把map中的值set到对应Object对象pt中
*/
userInfo = new UserInfo();
setBeanProperty(userInfo, parameter);
/*
* 3.采用object to xml 的方式封装xml字符串
*/
/*
* 4.释放资源
*/
close();
return xml;
}
/**
* 放值到Map对象中
*
* @param parameter
*/
private static void putValue
(Map parameter
) {
/*
* 实际开发中是查询数据库然后把相应的值put到Map的对象中, 但是此处的键key的值必须要和javabean中的字段名称一模一样,
* 多一个空格,大小写不一样的话都不行,这样后面都没有办法把值set到对象中
*/
parameter.put("username", "testuser");
parameter.put("password", "123456");
}
/**
* 把map中的值set到对应Object对象pt中
*
* @param pt
* @param map
* @throws Exception
*/
/*
* 全面地对类进行查询,返回一个我们可以进行详细研究以发现其属性、方法和事件的BeanInfo对象
*/
/*
* BeanInfo 返回这些信息的方法如下: getBeanDescriptor():
* 返回一个Bean叙词表(BeanDescriptor),包含bean的多方面信息(图标,显示名等)
* getPropertyDescriptors(): 返回一属性叙词表,返回的每个元素是一个PropertyDescriptor对象
* getMethodDescriptors(): 返回一方法叙词表 ,返回的每个元素是一个MethodDescriptor对象
* getEventSetDescriptors(): 返回一事件集叙词表 ,返回的每个元素是一个EventSetDescriptor对象
*/
for (int i = 0; i < pds.length; i++) {
Method methodGetX
= pd.
getWriteMethod();// getWriteMethod()获得应该用于写入属性值的方法
if (map.containsKey(pd.getName())) {// pd.getName()的值即username、password
String value
= (map.
get(pd.
getName())) == null ? "" : map.
get(
pd.getName()).toString();// 取得属性值
if (value != null && value.trim() != "") {
/*
* Object invoke(Object obj, Object... args)
* 对带有指定参数的指定对象调用由此 Method 对象表示的底层方法 obj - 从中调用底层方法的对象 args
* - 用于方法调用的参数 通俗点说就是,调用obj对象中value属性对应的set方法把值放入到obj对象中
*/
methodGetX.
invoke(obj,
new Object[] { value
});
}
}
}
}
/**
* 通过XStream类采用object to xml 的方式封装xml字符串
*
* @return
*/
private static String getXML
() {
XStream xstream = new XStream(new XppDriver(new XmlFriendlyReplacer(
"-_", "_")));// 用此种构造方法是为了去掉报文中下划线占两个字符的问题
xstream.alias("user_info", UserInfo.class);// 设置别名
// addImplicitCollection
sb.append("<?xml version=\"1.0\" encoding=\"gbk\"?>");
sb.append("\n");
sb.append(xstream.toXML(userInfo));
return sb.toString();
}
/**
* 释放Map对象中的资源
*/
private static void close() {
if (parameter != null && !parameter.isEmpty())
parameter.clear();
}
// =========================================【报文封装完成】============================================================
/**
* 测试的main方法
*
* @param args
* @throws Exception
*/
String result
= returnXML
();// 实际开发中,可以把这个返回值通过调用webservice接口或者是HTTP接口发送报文到交互的系统中
// 打印看看结果
System.
out.
println("================================\n");
System.
out.
println("\n================================");
}
}