浏览 6400 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (8) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-12-03
最近的项目中用到了XML,所以就写了个对象转换为XML文件的通用类。 package com.creawor.cbsms.client.xml.util; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.text.SimpleDateFormat; import java.util.HashMap; import java.util.Map; /** * <p> * Description: 反射机制工具类,根据传入的Obj, * 为生成xml文件提取所有属性和属性对应的值 * </p> * * * @author Administrator * @since 2008-12-1 * @version */ public class ReflectionUtil { //所有的系统类型 private static String[] allSysDefinedType = new String[] { "java.lang.String", "java.lang.Long", "long", "java.lang.Integer", "int", "java.lang.Short", "short", "java.lang.Byte", "byte", "java.lang.Float", "float", "java.lang.Double", "double", "java.util.Date", "java.lang,Char", "char", "java.lang.Boolean", "boolean", "java.sql.Timestamp" }; private static String dateFormatString = "yyyy-MM-dd HH:mm:ss"; //使用不可以是属性名前缀的*作为标识是否是用户自定义的类型 private static String userDefiendTypePrefix = "*"; /** * 根据传入的对象将对象的属性和该属性对应的值放入map * @param obj * 待映射属性和属性值的对象 * @param unReflectProp * 不需要映射属性和属性值的所有属性; * eg. CbsTargetTime对象中有DATE_FORMAT不需要映射则在该参数中添加 * CbsTargetTime.DATE_FORMAT * * @return Map * key = property name ; value = property value; * (如果属性为一个用户自定义类型的对象那么 * key = '*' + 'user defined type'; * value = map;map中key是属性,value是值,依次循环) */ public Map<String, Object> transformObjData2Map(Object obj, String[] unReflectProp) { Map<String, Object> rootMap = new HashMap<String, Object>(); Map<String, Object> dataMap = new HashMap<String, Object>(); rootMap.put(userDefiendTypePrefix + obj.getClass().getSimpleName(), dataMap); // 使用不可以是属性名前缀的*作为标识是否是用户自定义的类型 this.getObjPro(obj, unReflectProp, dataMap, obj.getClass().getName()); return rootMap; } /** * 得到传入对象的每个属性域, * 根据每个属性域得到属性域对应的值 * * @param obj * 待映射得到属性和值的对象 * * @param unReflectProp * 不需要映射属性和属性值的所有属性; * * @param className * 对象的类型名,如果传入对象为空时,用其新建一个对象 * @param dataMap * key=属性,value=属性的值 */ @SuppressWarnings("unchecked") private void getObjPro(Object obj, String[] unReflectProp, Map dataMap, String className) { try { Class clas; if (obj == null) { clas = Class.forName(className); obj = clas.newInstance(); } else { clas = Class.forName(obj.getClass().getName()); } //得到obj类的所有属性 Field[] fileds = clas.getDeclaredFields(); for (Field field : fileds) { String fieldName = field.getName(); String fieldType = field.getType().getName(); //如果该属性是不需要映射的属性则跳出循环 if (!reflectPropOrNot(obj.getClass().getSimpleName() + "." + fieldName, unReflectProp)) { continue; } //属性名的第一个字母大写,与get或者is组成方法名 String firstCharUpper = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1, fieldName.length()); Method method; //如果是boolean型则方法名为is*;反之为get* if (isBooleanType(fieldType)) { method = clas.getMethod("is" + firstCharUpper, null); } else { method = clas.getMethod("get" + firstCharUpper, null); } if (isSysDefinedType(fieldType)) { //如果是系统类型则添加进入map String formatDateStr = isTimeType(fieldType, method, obj); if (formatDateStr != null) { dataMap.put(fieldName, formatDateStr); continue; } dataMap.put(fieldName, method.invoke(obj, null) == null ? "" : method .invoke(obj, null)); } else { //如果不是系统类型对象则key = * + 属性名 ; value = map;循环迭代 Map dateMap2 = new HashMap(); this.getObjPro(method.invoke(obj, null), unReflectProp, dateMap2, fieldType); dataMap.put(userDefiendTypePrefix + field.getType().getSimpleName(), dateMap2); } } } catch (Exception e) { // TODO Auto-generated catch block System.out.println("映射属性和属性所对应值出现异常!!"); e.printStackTrace(); } } /** * 验证属性是否是要通过反射机制得到名称和值 * @param fieldName * 待验证的属性 * @return * true 要利用反射机制的到属性名和值 * false 不需要利用反射机制的到属性名和值 */ private boolean reflectPropOrNot(String fieldName, String[] unReflectProp) { if (unReflectProp == null) { return true; } for (String propName : unReflectProp) { if (propName.equals(fieldName)) { return false; } } return true; } /** * 验证属性的类型是否是系统定义的类型 * @param fieldType * 待验证类型的名称 * @return * true 是系统定义的对象 * false 用户定义的对象 */ private boolean isSysDefinedType(String fieldType) { for (String type : allSysDefinedType) { if (fieldType.equals(type)) { return true; } } return false; } /** * 如果该属性是日期属性则根据要输出的类型返回字符串,反之返回null * @param fileType * @param method * @param obj * @return * @throws IllegalAccessException * @throws InvocationTargetException */ private String isTimeType(String fileType, Method method, Object obj) throws IllegalAccessException, InvocationTargetException { if (fileType.equals("java.util.Date") || fileType.equals("java.sql.Timestamp")) { if (method.invoke(obj, null) == null) { return null; } SimpleDateFormat sdf = new SimpleDateFormat(dateFormatString); return sdf.format(method.invoke(obj, null)); } else { return null; } } public boolean isBooleanType(String fieldType) { if (fieldType.equals("java.util.Boolean") || fieldType.equals("boolean")) { return true; } return false; } public static void setDateFormatString(String dateFormatString) { ReflectionUtil.dateFormatString = dateFormatString; } public static String getUserDefiendTypePrefix() { return userDefiendTypePrefix; } public static void setUserDefiendTypePrefix(String userDefiendTypePrefix) { ReflectionUtil.userDefiendTypePrefix = userDefiendTypePrefix; } }
package com.creawor.cbsms.client.xml.util; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.List; import java.util.Map; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.XMLWriter; /** * <p> * Description: XML生成类,将传入的对象生成XML文件 * * </p> * * * @author Administrator * @since 2008-12-1 * @version */ public class XMLProcessor { private ReflectionUtil reflectionUtil; /** * 建立一个XML文档,文档名由输入参数决定 * * @param obj * @param unReflectProp * @param filename * * @return */ @SuppressWarnings("unchecked") public void createXMLFile(List<Object> objs, String[] unReflectProp, String filename) throws IndexOutOfBoundsException, IOException { reflectionUtil = new ReflectionUtil(); // 建立Document对象 Document document = DocumentHelper.createDocument(); // 添加根节点进入Document Element rootElement = document.addElement(objs.get(0).getClass() .getSimpleName() + "s"); for (Object obj : objs) { Map<String, Object> rootMap = reflectionUtil.transformObjData2Map( obj, unReflectProp); String rootString = ReflectionUtil.getUserDefiendTypePrefix() + obj.getClass().getSimpleName(); map2Node((Map) rootMap.get(rootString), rootElement, rootString); } // 格式化输出XML,换行缩进 OutputFormat format = OutputFormat.createPrettyPrint(); // 设置字符集 format.setEncoding("GBK"); // 将document中的内容写入文件中 XMLWriter writer = new XMLWriter(new FileWriter(new File(filename)), format); writer.write(document); writer.close(); } /** * 将映射为 对象的属性-->属性对应的值 的map转换为xml文件中的各个节点 * @param dataMap * * @param objNode * 父节点,map中创建的节点都是其子节点 * @param objClass * 父节点的名称 */ @SuppressWarnings("unchecked") private void map2Node(Map<String, Object> dataMap, Element objNode, String objName) { //第一个字符是*,创建*后面字符为名称的节点 Element objElement = objNode.addElement(objName.substring(1)); if (isAllSysType(dataMap)) { //如果该对象中全部是系统类型则全部添加到objElement节点下 for (String propName : dataMap.keySet()) { createNextNode(objElement, propName, dataMap.get(propName) + ""); } } else { //如果该对象中还有用户自定义类型则系统类型添加进入 objNameInfo节点下,用户自定义类型添加进入 自定义类型名成节点下 Element infoNode = objElement.addElement(objName.substring(1) + "Info"); for (String propName : dataMap.keySet()) { if (propName.startsWith("*")) { map2Node((Map) dataMap.get(propName), objElement, propName); } else { createNextNode(infoNode, propName, dataMap.get(propName) + ""); } } } } /** * 根据name和text创建elements的子节点 * * @param element * @param nodeName * @param text */ private void createNextNode(Element element, String nodeName, String text) { Element nextElement = element.addElement(nodeName); if (text == null) { return; } nextElement.setText(text); } /** * 是否是系统类,如果前缀是*则是自定义类型 * @param dataMap * @return */ private boolean isAllSysType(Map<String, Object> dataMap) { for (String propName : dataMap.keySet()) { if (propName.startsWith("*")) { return false; } } return true; } public ReflectionUtil getReflectionUtil() { return reflectionUtil; } public void setReflectionUtil(ReflectionUtil reflectionUtil) { this.reflectionUtil = reflectionUtil; } }
package com.creawor.cbsms.client.xml.service; import java.io.IOException; import java.util.List; import com.creawor.cbsms.client.xml.util.XMLProcessor; /** * <p> * Description: 提供对象转换为XML的调用接口 * * </p> * * * @author Administrator * @since 2008-12-2 * @version */ public class Object2XMLHander { private XMLProcessor xmlProcessor; /** * 生成一个XML文档,文档名由输入参数决定 * * @param objs * 待转换为XML文件的对象集合 * * @param unReflectProp * 不需要映射进入XML属性;如果全部要映射进入XML文件则传入null * eg. CbsTargetTime对象中有DATE_FORMAT不需要映射则在该参数中添加 * CbsTargetTime.DATE_FORMAT * * @param filename * 需建立Xml文件的完全路径和文件名 * * @return 返回操作结果, * 0表失败, 1表成功 */ @SuppressWarnings("unchecked") public int createXMLFile(List objs, String[] unReflectProp, String filename) { try { xmlProcessor = new XMLProcessor(); xmlProcessor.createXMLFile(objs, unReflectProp, filename); return 1; } catch (IndexOutOfBoundsException e) { // TODO Auto-generated catch block //System.out.println("传入的对象数组长度为零!"); e.printStackTrace(); return 0; } catch (IOException e) { // TODO Auto-generated catch block System.out.println("生成XML异常!"); e.printStackTrace(); return 0; } } }
package com.creawor.cbsms.client.xml.test; import java.sql.Timestamp; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; import com.creawor.cbsms.client.model.CbsMessage; import com.creawor.cbsms.client.model.CbsTargetTime; import com.creawor.cbsms.client.xml.service.Object2XMLHander; import com.creawor.cbsms.client.xml.util.XMLProcessor; public class MyTest { public static void main(String[] args) { CbsMessage message = new CbsMessage(); message.setChannelId(1); message.setData("你好 world"); message.setBcEndType(1); message.setMessageNum(12); CbsMessage message2 = new CbsMessage(); message2.setChannelId(2); message2.setData("hello world2"); message2.setBcEndType(2); message2.setMessageNum(122); CbsTargetTime ctt = new CbsTargetTime(); ctt.setFixedTime("fixtime"); Calendar cal = Calendar.getInstance(); ctt.setEndDate(new Timestamp(cal.getTimeInMillis())); message.setCbsTargetTime(ctt); String[] unReflectProp = new String[] { "CbsTargetTime.DATE_FORMAT", "CbsTargetTime.TIME_FORMAT", "CbsTargetTime.DATE_TIME_FORMAT", "CbsTargetTime.TIME_TYPE_FIXED_TIME", "CbsTargetTime.TIME_TYPE_TOPIC", "CbsTargetTime.TIME_TYPE_BC_NOW", "CbsTargetTime.TIME_TYPE_REAL_TIME", "CbsTargetTime.TIME_TYPE_CRON_EXPRESSION", "CbsTargetTime.TIME_TYPE_RANGE" }; List<CbsMessage> messages = new ArrayList<CbsMessage>(); messages.add(message); messages.add(message2); UserInfo user = new UserInfo(); user.setPassword("password"); user.setUsername("username"); ctt.setUser(user); Object2XMLHander hander = new Object2XMLHander(); hander.createXMLFile(messages, unReflectProp, "E:\\maosenFirst2.xml"); } }
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-12-03
xstream 不好吗,好像两行代码就可以实现这个功能吧!
|
|
返回顶楼 | |
发表时间:2008-12-03
有个东西叫XML系列化和反系列化吧?
|
|
返回顶楼 | |
发表时间:2008-12-03
JAXB 也可以的
|
|
返回顶楼 | |
发表时间:2008-12-03
xtream不错,很轻量,序列化和反序列化都相当简单。JAXB太笨重了。
|
|
返回顶楼 | |
发表时间:2008-12-03
开头写了老大一个数组,为啥不用枚举?还有就是开源已经有很不错的了,可以参考一下。不过还是赞一下,技术没有好坏,只有好不好用
|
|
返回顶楼 | |
发表时间:2009-12-02
推荐xtream
|
|
返回顶楼 | |
发表时间:2009-12-02
代码还是很清晰的。
自己已经实现了,为什么还要用别人的。没干的话用现成的话还可以考虑。 |
|
返回顶楼 | |
发表时间:2009-12-02
最后修改:2009-12-02
yangfudong 写道 代码还是很清晰的。
自己已经实现了,为什么还要用别人的。没干的话用现成的话还可以考虑。 作为系统负责人,如果有开源好用,自己造好了轮子,我也会要求砸了用开源产品。开源产品背后是一个社区。帮你维护、测试、文档、培训人。你不可能会做得更好,而且以后招人也非常容易,不会有大的风险。 java平台发展到今天,更多应该是去整合各类成熟组件,能做好才是真正的牛! 这个还是推荐你使用xstream |
|
返回顶楼 | |