java bean和xml相互转换

来源:互联网 发布:实况足球2017捏脸数据 编辑:程序博客网 时间:2024/05/16 04:06

这几天在做微信公众号

做的过程中想找个java bean转xml的工具,找了几个用着不知道是配置不好还是怎么回事,都会有一些问题,

然后脑子一热谢了一个javabean和xml的转换的工具里,自己用着还行,虽然有一些约束吧 ,

还是贴出来记录一下 

 

 

顺便你提一下下,这个转换工具支持属性为集合、数组和非基本属性的对象。

 

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是小写的,其他的标签都是第一个字符大写的。whyroot = 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);//开始创建xmlStringBuffer 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的就可以了 

已添加附件