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 */ /* 假设报文格式如下: testuser password */ /** * 定义一个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(""); 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================================"); } }