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 { |
// 此处的属性名称就是最后发送报文中的字段名称 |
private String username; |
private String password; |
// 这几个类的使用时javabean的属性的类型不能有多种(如:String和int不能共存、但是int和long可以共存),否则后面会报异常 |
public String getUsername() { |
return username; |
} |
public void setUsername(String username) { |
this .username = username; |
} |
public String getPassword() { |
return password; |
} |
public void setPassword(String password) { |
this .password = password; |
} |
} |
// =========================================【javabean定义完成】============================================================ |
public class XML_OBJTOXML { |
private static Map parameter = new HashMap(); |
private static UserInfo userInfo = null ; |
/** |
* 整合4个方法,提供一个程序的访问的接口 |
* |
* @return |
* @throws Exception |
*/ |
public static String returnXML() throws Exception { |
/* |
* 1.放值到map对象中 |
*/ |
putValue(parameter); |
/* |
* 2.把map中的值set到对应Object对象pt中 |
*/ |
userInfo = new UserInfo(); |
setBeanProperty(userInfo, parameter); |
/* |
* 3.采用object to xml 的方式封装xml字符串 |
*/ |
String xml = getXML(); |
/* |
* 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 |
*/ |
private static void setBeanProperty(Object obj, Map map) throws Exception { |
/* |
* 全面地对类进行查询,返回一个我们可以进行详细研究以发现其属性、方法和事件的BeanInfo对象 |
*/ |
BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass()); |
/* |
* BeanInfo 返回这些信息的方法如下: getBeanDescriptor(): |
* 返回一个Bean叙词表(BeanDescriptor),包含bean的多方面信息(图标,显示名等) |
* getPropertyDescriptors(): 返回一属性叙词表,返回的每个元素是一个PropertyDescriptor对象 |
* getMethodDescriptors(): 返回一方法叙词表 ,返回的每个元素是一个MethodDescriptor对象 |
* getEventSetDescriptors(): 返回一事件集叙词表 ,返回的每个元素是一个EventSetDescriptor对象 |
*/ |
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors(); |
for ( int i = 0 ; i < pds.length; i++) { |
PropertyDescriptor pd = pds[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 |
StringBuffer sb = new StringBuffer(); |
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 |
*/ |
public static void main(String[] args) throws Exception { |
String result = returnXML(); // 实际开发中,可以把这个返回值通过调用webservice接口或者是HTTP接口发送报文到交互的系统中 |
// 打印看看结果 |
System.out.println( "================================\n" ); |
System.out.println(result); |
System.out.println( "\n================================" ); |
} |
} |