这几天在做微信公众号
做的过程中想找个java bean转xml的工具,找了几个用着不知道是配置不好还是怎么回事,都会有一些问题,
然后脑子一热谢了一个javabean和xml的转换的工具里,自己用着还行,虽然有一些约束吧 ,
还是贴出来记录一下?
?
?
顺便你提一下下,这个转换工具支持属性为集合、数组和非基本属性的对象。
?
class="java">package com.uke.util; import java.io.IOException; import java.io.StringReader; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import javax.xml.parsers.ParserConfigurationException; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.JDOMException; import org.jdom2.input.SAXBuilder; import org.xml.sax.InputSource; import com.uke.bean.Message; import com.uke.bean.remsg.Music; import com.uke.bean.remsg.ReMusicMsg; /** * * @author q821424508@sina.com * */ public class BeanUtil { /** * 对象转为xml字符串 * @param obj * 需要转xml的对象 * @param root * xml跟标签的名称,默认为xml * @return * 返回转换后的xml * <br> * 说明: * <br> * 目前来说这个方法能够把对象转换成xml字符串没有什么问题,但是对bean类有一定的要求: * <br> * 1.<strong>bean类的没有需要设置的属性必须有getter、setter方法</strong> * 2.<strong>生成的xml不会设置到xml的属性</strong> * @throws InstantiationException * @throws NoSuchMethodException * @throws SecurityException * @throws IllegalAccessException * @throws IllegalArgumentException * @throws InvocationTargetException * @throws JDOMException * @throws IOException * @throws ParserConfigurationException */ public static String convertToXml(Object obj,String root) throws InstantiationException { //加这一句判断是为了方便递归调用,如果root为空,那么视为第一次调用,也就是xml的根 if(StrUtil.isNullOrEmptyOrBlank(root)){ root = "xml"; } if(root.equalsIgnoreCase("item")){ ////、!!为什么只有这个以的item的i是小写的,其他的标签都是第一个字符大写的。why root = root.toLowerCase(); } try { //声明一个列表 存放需要转换成xml类的所有设计的父类 //这个地方没有涉及到属性为类的地方,应为下面的处理方法是,如果属性是类的话,就递归调用这个方法,所以没有什么需要担心的 List<Class<?>> cl = new ArrayList<Class<?>>(); //获取对象的类 Class<?> clazz = obj.getClass(); //判断,如果父类不是Object的话把所有的类放到上面声明的list里面 String simpleName = clazz.getSimpleName(); while (!"Object".equals(simpleName)) { cl.add(clazz); clazz = clazz.getSuperclass(); simpleName = clazz.getSimpleName(); } //上面是从子类开始存放的,所以这里要反转 Collections.reverse(cl); //开始创建xml StringBuffer xml = new StringBuffer("<"+root+">\n"); for (Class<?> cz : cl) { //System.out.println("list " + cz.getName()); //获取类里面声明的所有属性,之所以上面要获取父级的类,时应为这里只能获取当前类的声明方法,无法获取到集成来的方法 Field[] fs = cz.getDeclaredFields(); for (Field f : fs) { // System.out.println("f.getName() = "+f.getName()); // System.out.println("f.getName() = "+f.getType().getName()); // //获取属性的类型 Class<?> ct =f.getType(); //获取类对应的名称 String ctName = ct.getSimpleName(); String fName = f.getName(); String firstUpperName = fName.substring(0, 1).toUpperCase()+fName.substring(1); //System.out.println(); //当然,如果类是基础类型的直接设值就可以了 if("int".equals(ctName) || "long".equals(ctName)|| "double".equals(ctName)|| "float".equals(ctName) || "char".equals(ctName)){ xml.append(getFieldXml(f,cz,obj)).append("\n"); }else if("String".equals(ctName)||"char".equals(ctName)){ xml.append(getFieldXml(f,cz,obj)).append("\n"); }else { //如果属性不是基础类型的,则需要递归调用,也就是把上面的方法冲走一遍 //通过执行get方法,获取对象的返回值。 String methodName = "get" +firstUpperName; Class<?>[] cnull = null; Method m=cz.getMethod(methodName, cnull); Object[] osnull =null; Object reto=m.invoke(obj, osnull); if(null!=reto){ if(reto instanceof Collection<?>){ //如果结果是集合类型,那么获取子元素继续 xml.append("<"+firstUpperName+">\n"); Collection<Object> ol = (Collection<Object>)reto; for(Object o:ol){ xml.append(convertToXml(o,o.getClass().getSimpleName())); } xml.append("</"+firstUpperName+">\n"); }else if(reto instanceof Array){ //如果结果是数组类型,那么获取数组里每个元素继续 xml.append("<"+firstUpperName+">\n"); Object[] ol = (Object[])reto; for(Object o:ol){ xml.append(convertToXml(o,o.getClass().getSimpleName())); } xml.append("</"+firstUpperName+">\n"); } else{ //如果返回值不为null 执行递归调用 xml.append(convertToXml(reto,ctName)); } }else{ //如果为null,直接在这个属性里面设置为空就可以了 xml.append("<"+firstUpperName+">\n</"+firstUpperName+">\n"); } } } } xml.append("</"+root+">\n"); return xml.toString(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return null; } /** * 通过Filed,Class,和Objec对象获取需要生成的对应Filed的字符串 * @param f * @param cz * @param obj * @return * @throws NoSuchMethodException * @throws SecurityException * @throws IllegalAccessException * @throws IllegalArgumentException * @throws InvocationTargetException */ private static String getFieldXml(Field f, Class<?> cz, Object obj) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{ String fName = f.getName(); String firstUpperName = fName.substring(0, 1).toUpperCase()+fName.substring(1); String str = "<"+firstUpperName+">"; String methodName = "get" +firstUpperName; Class<?>[] cnull = null; Method m=cz.getMethod(methodName, cnull); Object[] osnull =null; Object reto=m.invoke(obj, osnull); if(null!=reto){ Class<?> ct =f.getType(); String ctName = ct.getSimpleName(); if("int".equals(ctName) || "long".equals(ctName)){ if("0".equals(reto.toString())){ System.err.println(fName +" 对应的值为0"); } str +=reto.toString(); }else if("double".equals(ctName)|| "float".equals(ctName)){ if("0.0".equals(reto.toString())||"0".equals(reto.toString())){ System.err.println(fName +" 对应的值为0"); } str +=reto.toString(); }else{ str +="<![CDATA["+reto.toString()+"]]>"; } }else{ System.err.println(fName +" 对应的值为空"); } str +="</"+firstUpperName+">"; return str; } /** * 通过xml字符串转换成给定类的对象 * @param xml * 需要转成对象的字符串 * @param c * 返回对象的类[Class] * @return * 返回对象的实例 * <br> * 1.转换过程中不会操作任何xml的属性操作,值是一个标签对应一个属性来操作的 * <br> * 2.参数Class<?> c对应的类,需要设置的属性都必须有getter,setter方法 */ public static <T> T converyToJavaBean(String xml, Class<T> c) { T t = null; try { t= c.newInstance(); SAXBuilder sb = new SAXBuilder(); StringReader read = new StringReader(xml); InputSource source = new InputSource(read); Document doc = sb.build(source); Element root =doc.getRootElement(); convery(root,c,t); } catch (Exception e) { e.printStackTrace(); } return t; } private static void convery(Element e,Class<?> clazz,Object o) throws SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException{ // System.out.println("el.size = "+el.size()); // String text = e.getTextTrim(); // System.out.println("text = "+text); String en =e.getName(); if("xml".equals(en)){ List<Element> el = e.getChildren(); for(Element e1:el){ convery(e1,clazz,o); } }else{ List<Element> el = e.getChildren(); if(el.size()>0){ String childClassName =e.getName(); String methodName = "get" +childClassName.substring(0, 1).toUpperCase()+childClassName.substring(1); Class<?> clazz1 = null; Method[] ms = clazz.getMethods(); for(Method m:ms){ // System.out.println(m.getName()); if(methodName.equals(m.getName())){ clazz1 = m.getReturnType(); } } // try { // clazz1 = Class.forName(ncn); // } catch (Exception e2) { // System.err.println(ncn + " 实例化失败,请检查是否存在这个类 "); // } if(null==clazz1){ //没有找到对应的类,这里只是忽略 System.out.println(methodName + " 方法未找到,或者返回类型不正确 "); return; } Object o1 = clazz1.newInstance(); try { //反射获取set方法,帮o1的值设置进o里面 Method m =clazz.getMethod(methodName, clazz1); m.invoke(o, o1); } catch (Exception e2) { //应该是没有找到对应的方法,忽略 System.err.println(methodName +" 方法调用失败,请检查方法是否存在"); return ; } for(Element e1:el){ convery(e1,clazz1,o1); } }else{ String eName = e.getName(); String methodName = "set" +eName.substring(0, 1).toUpperCase()+eName.substring(1); Method[] ms=clazz.getMethods(); for(Method m:ms){ if(m.getName().equals(methodName)){ Class<?>[] c= m.getParameterTypes(); //目前只支持带一个参数的情况 String text = e.getTextTrim(); Object v = null; String cn = c[0].getSimpleName(); if("int".equals(cn)){ v = Integer.parseInt(text); }else if("long".equals(cn)){ v= Long.parseLong(text); }else if("double".equals(cn)){ v = Double.parseDouble(text); }else if("float".equals(cn)){ v = Float.parseFloat(text); }else{ v = text; } m.invoke(o,v); } } } } } public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, JDOMException, IOException, ParserConfigurationException, InstantiationException { ReMusicMsg rmm = new ReMusicMsg(); Music m = new Music(); m.setTitle("小苹果"); m.setDescription("小苹果"); m.setMusicUrl("http://yinyueshiting.baidu.com/data2/music/122112390/12012502946800128.mp3?xcode=b7d19aa0a1f43850273d9292ca2357ec3f8882ee658cd7de"); m.setHQMusicUrl("http://yinyueshiting.baidu.com/data2/music/122112390/12012502946800128.mp3?xcode=b7d19aa0a1f43850273d9292ca2357ec3f8882ee658cd7de"); rmm.setMusic(m); rmm.setMsgType("music"); rmm.setCreateTime((int)(System.currentTimeMillis()/1000)); rmm.setFromUserName("gh_32a91b043d76"); rmm.setToUserName("os6Z4swOSB6pzVDtA90g0Fq4Dz_4"); rmm.setFuncFlag(1); rmm.setMsgId(6051426418514665443l); rmm.setMsgType("music"); String xml =convertToXml(rmm,null); System.out.println(xml); xml = "<xml><ToUserName><![CDATA[gh_32a91b043d76]]></ToUserName>/n<FromUserName><![CDATA[os6Z4swOSB6pzVDtA90g0Fq4Dz_4]]></FromUserName>/n<CreateTime>1409041861</CreateTime>/n<MsgType><![CDATA[text]]></MsgType>/n<Content><![CDATA[哈哈]]></Content>/n<MsgId>6051788711890992105</MsgId>/n</xml>/n"; xml =xml.replaceAll(">/n", ">"); System.out.println(xml); Message ms = converyToJavaBean(xml, Message.class); System.out.println(ms.getMsgType()); } }
?
使用和约束什么的,在方法头部已经写出来了,这里就不多说了,
如果你想测试的话,可能需要一下jar和一些自定义的类,
自定义的类你可以更具用到的属性直接写一个就行了,就是简单的属性和getter setter方法?
?
jar包应该只要jdom的就可以了?
已添加附件?
?