Object转XML && XML转Object 测试类:
package com.insist.objectxml; import com.insist.objectxml.common.JaxbMapper; import com.insist.objectxml.person.Body; import com.insist.objectxml.person.Person; /** * 描述:测试对象——>XML || XML——>对象<br> * 作者:liqijing <br> * 修改日期:2015-4-6下午07:38:17 <br> * E-mail: lijinginsistsmile@163.com <br> */ public class ObjectXml { public static void main(String[] args) { String reqXml = getXml(); System.out.println("输出XML:"+"\n"+reqXml); System.out.println("解析XML-->Object"+"==========================================="); Person person = getPerson(reqXml); System.out.println("id="+person.getPerId()+",name="+person.getPerName()+",age="+person.getPerAge()+",sex="+person.getPerSex()+",email="+person.getEmail()); } /** * 方法名称: getXml<br> * 描述: Object --> XML * 作者: liqijing * 修改日期:2015-4-6下午07:46:03 * @param body * @param encoding * @return */ public static String getXml(){ Body body = new Body(); body.setPerson(initPerson()); String reqXml = JaxbMapper.toXml(body,"GBK") ; if(reqXml == null){ return "组装XML出错!" ; } return reqXml ; } /** * 方法名称: getPerson<br> * 描述:XML ---> Object * 作者: liqijing * 修改日期:2015-4-6下午07:47:21 * @param reqXml * @return */ public static Person getPerson(String reqXml){ Body body = JaxbMapper.fromXml(reqXml,Body.class) ; return body.getPerson() ; } /** * 方法名称: initPerson<br> * 描述:初始化person对象 * 作者: liqijing * 修改日期:2015-4-6下午07:38:12 * @return */ public static Person initPerson(){ Person person = new Person("100000","马云","24","男","lijinginsistsmile@163.com"); return person ; } }
JaxbMapper生成&&解析:
/******************************************************************************* * Copyright (c) 2005,2014 springside.github.io * * Licensed under the Apache License,Version 2.0 (the "License"); *******************************************************************************/ package com.insist.objectxml.common; import java.io.StringReader; import java.io.StringWriter; import java.util.Collection; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAnyElement; import javax.xml.namespace.QName; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; import com.insist.objectxml.exception.Exceptions; /** * 使用Jaxb2.0实现XML<->Java Object的Mapper. * * 在创建时需要设定所有需要序列化的Root对象的Class. * 特别支持Root对象是Collection的情形. * * @author calvin */ public class JaxbMapper { private static final Exceptions Exceptions = null; private static ConcurrentMap<Class,JAXBContext> jaxbContexts = new ConcurrentHashMap<Class,JAXBContext>(); /** * Java Object->Xml without encoding. */ public static String toXml(Object root) { Class clazz = Reflections.getUserClass(root); return toXml(root,clazz,null); } /** * Java Object->Xml with encoding. */ public static String toXml(Object root,String encoding) { Class clazz = Reflections.getUserClass(root); return toXml(root,encoding); } /** * Java Object->Xml with encoding. */ public static String toXml(Object root,Class clazz,String encoding) { try { StringWriter writer = new StringWriter(); createMarshaller(clazz,encoding).marshal(root,writer); return writer.toString(); } catch (JAXBException e) { throw Exceptions.unchecked(e); } } /** * Java Collection->Xml without encoding,特别支持Root Element是Collection的情形. */ public static String toXml(Collection<?> root,String rootName,Class clazz) { return toXml(root,rootName,null); } /** * Java Collection->Xml with encoding,String encoding) { try { CollectionWrapper wrapper = new CollectionWrapper(); wrapper.collection = root; JAXBElement<CollectionWrapper> wrapperElement = new JAXBElement<CollectionWrapper>(new QName(rootName),CollectionWrapper.class,wrapper); StringWriter writer = new StringWriter(); createMarshaller(clazz,encoding).marshal(wrapperElement,writer); return writer.toString(); } catch (JAXBException e) { throw Exceptions.unchecked(e); } } /** * Xml->Java Object. */ public static <T> T fromXml(String xml,Class<T> clazz) { try { StringReader reader = new StringReader(xml); return (T) createUnmarshaller(clazz).unmarshal(reader); } catch (JAXBException e) { throw Exceptions.unchecked(e); } } /** * 创建Marshaller并设定encoding(可为null). * 线程不安全,需要每次创建或pooling。 */ public static Marshaller createMarshaller(Class clazz,String encoding) { try { JAXBContext jaxbContext = getJaxbContext(clazz); Marshaller marshaller = jaxbContext.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,Boolean.TRUE); if (StringUtils.isNotBlank(encoding)) { marshaller.setProperty(Marshaller.JAXB_ENCODING,encoding); } return marshaller; } catch (JAXBException e) { throw Exceptions.unchecked(e); } } /** * 创建UnMarshaller. * 线程不安全,需要每次创建或pooling。 */ public static Unmarshaller createUnmarshaller(Class clazz) { try { JAXBContext jaxbContext = getJaxbContext(clazz); return jaxbContext.createUnmarshaller(); } catch (JAXBException e) { throw Exceptions.unchecked(e); } } protected static JAXBContext getJaxbContext(Class clazz) { Validate.notNull(clazz,"'clazz' must not be null"); JAXBContext jaxbContext = jaxbContexts.get(clazz); if (jaxbContext == null) { try { jaxbContext = JAXBContext.newInstance(clazz,CollectionWrapper.class); jaxbContexts.putIfAbsent(clazz,jaxbContext); } catch (JAXBException ex) { throw new RuntimeException("Could not instantiate JAXBContext for class [" + clazz + "]: " + ex.getMessage(),ex); } } return jaxbContext; } /** * 封装Root Element 是 Collection的情况. */ public static class CollectionWrapper { @XmlAnyElement protected Collection<?> collection; } }
/******************************************************************************* * Copyright (c) 2005,Version 2.0 (the "License"); *******************************************************************************/ package com.insist.objectxml.common; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * 反射工具类. * * 提供调用getter/setter方法,访问私有变量,调用私有方法,获取泛型类型Class,被AOP过的真实类等工具函数. * * @author calvin */ public class Reflections { private static final String SETTER_PREFIX = "set"; private static final String GETTER_PREFIX = "get"; private static final String CGLIB_CLASS_SEPARATOR = "$$"; private static Logger logger = LoggerFactory.getLogger(Reflections.class); /** * 调用Getter方法. */ public static Object invokeGetter(Object obj,String propertyName) { String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(propertyName); return invokeMethod(obj,getterMethodName,new Class[] {},new Object[] {}); } /** * 调用Setter方法,仅匹配方法名。 */ public static void invokeSetter(Object obj,String propertyName,Object value) { String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(propertyName); invokeMethodByName(obj,setterMethodName,new Object[] { value }); } /** * 直接读取对象属性值,无视private/protected修饰符,不经过getter函数. */ public static Object getFieldValue(final Object obj,final String fieldName) { Field field = getAccessibleField(obj,fieldName); if (field == null) { throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]"); } Object result = null; try { result = field.get(obj); } catch (IllegalAccessException e) { logger.error("不可能抛出的异常{}",e.getMessage()); } return result; } /** * 直接设置对象属性值,不经过setter函数. */ public static void setFieldValue(final Object obj,final String fieldName,final Object value) { Field field = getAccessibleField(obj,fieldName); if (field == null) { throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]"); } try { field.set(obj,value); } catch (IllegalAccessException e) { logger.error("不可能抛出的异常:{}",e.getMessage()); } } /** * 直接调用对象方法,无视private/protected修饰符. * 用于一次性调用的情况,否则应使用getAccessibleMethod()函数获得Method后反复调用. * 同时匹配方法名+参数类型, */ public static Object invokeMethod(final Object obj,final String methodName,final Class<?>[] parameterTypes,final Object[] args) { Method method = getAccessibleMethod(obj,methodName,parameterTypes); if (method == null) { throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]"); } try { return method.invoke(obj,args); } catch (Exception e) { throw convertReflectionExceptionToUnchecked(e); } } /** * 直接调用对象方法,无视private/protected修饰符, * 用于一次性调用的情况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用. * 只匹配函数名,如果有多个同名函数调用第一个。 */ public static Object invokeMethodByName(final Object obj,final Object[] args) { Method method = getAccessibleMethodByName(obj,methodName); if (method == null) { throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]"); } try { return method.invoke(obj,args); } catch (Exception e) { throw convertReflectionExceptionToUnchecked(e); } } /** * 循环向上转型,获取对象的DeclaredField,并强制设置为可访问. * * 如向上转型到Object仍无法找到,返回null. */ public static Field getAccessibleField(final Object obj,final String fieldName) { Validate.notNull(obj,"object can't be null"); Validate.notBlank(fieldName,"fieldName can't be blank"); for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) { try { Field field = superClass.getDeclaredField(fieldName); makeAccessible(field); return field; } catch (NoSuchFieldException e) {// NOSONAR // Field不在当前类定义,继续向上转型 } } return null; } /** * 循环向上转型,获取对象的DeclaredMethod,并强制设置为可访问. * 如向上转型到Object仍无法找到,返回null. * 匹配函数名+参数类型。 * * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj,Object... args) */ public static Method getAccessibleMethod(final Object obj,final Class<?>... parameterTypes) { Validate.notNull(obj,"object can't be null"); Validate.notBlank(methodName,"methodName can't be blank"); for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) { try { Method method = searchType.getDeclaredMethod(methodName,parameterTypes); makeAccessible(method); return method; } catch (NoSuchMethodException e) { // Method不在当前类定义,返回null. * 只匹配函数名。 * * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,Object... args) */ public static Method getAccessibleMethodByName(final Object obj,final String methodName) { Validate.notNull(obj,"methodName can't be blank"); for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) { Method[] methods = searchType.getDeclaredMethods(); for (Method method : methods) { if (method.getName().equals(methodName)) { makeAccessible(method); return method; } } } return null; } /** * 改变private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。 */ public static void makeAccessible(Method method) { if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) && !method.isAccessible()) { method.setAccessible(true); } } /** * 改变private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。 */ public static void makeAccessible(Field field) { if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) || Modifier.isFinal(field.getModifiers())) && !field.isAccessible()) { field.setAccessible(true); } } /** * 通过反射,获得Class定义中声明的泛型参数的类型,注意泛型必须定义在父类处 * 如无法找到,返回Object.class. * eg. * public UserDao extends HibernateDao<User> * * @param clazz The class to introspect * @return the first generic declaration,or Object.class if cannot be determined */ public static <T> Class<T> getClassGenricType(final Class clazz) { return getClassGenricType(clazz,0); } /** * 通过反射,获得Class定义中声明的父类的泛型参数的类型. * 如无法找到,返回Object.class. * * 如public UserDao extends HibernateDao<User,Long> * * @param clazz clazz The class to introspect * @param index the Index of the generic ddeclaration,start from 0. * @return the index generic declaration,or Object.class if cannot be determined */ public static Class getClassGenricType(final Class clazz,final int index) { Type genType = clazz.getGenericSuperclass(); if (!(genType instanceof ParameterizedType)) { logger.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType"); return Object.class; } Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); if ((index >= params.length) || (index < 0)) { logger.warn("Index: " + index + ",Size of " + clazz.getSimpleName() + "'s Parameterized Type: " + params.length); return Object.class; } if (!(params[index] instanceof Class)) { logger.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter"); return Object.class; } return (Class) params[index]; } public static Class<?> getUserClass(Object instance) { Validate.notNull(instance,"Instance must not be null"); Class clazz = instance.getClass(); if ((clazz != null) && clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) { Class<?> superClass = clazz.getSuperclass(); if ((superClass != null) && !Object.class.equals(superClass)) { return superClass; } } return clazz; } /** * 将反射时的checked exception转换为unchecked exception. */ public static RuntimeException convertReflectionExceptionToUnchecked(Exception e) { if ((e instanceof IllegalAccessException) || (e instanceof IllegalArgumentException) || (e instanceof NoSuchMethodException)) { return new IllegalArgumentException(e); } else if (e instanceof InvocationTargetException) { return new RuntimeException(((InvocationTargetException) e).getTargetException()); } else if (e instanceof RuntimeException) { return (RuntimeException) e; } return new RuntimeException("Unexpected Checked Exception.",e); } }
Person类
package com.insist.objectxml.person; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlType; /** * 描述:object转xml实体类<br> * 作者:liqijing <br> * 修改日期:2015-4-6下午07:29:49 <br> * E-mail: lijinginsistsmile@163.com <br> */ @XmlType(name="Person",propOrder={"perId","perName","perAge","perSex","email"}) public class Person { private String perId; private String perName ; private String perAge ; private String perSex ; private String email ; @XmlElement(name = "PerId") public String getPerId() { return perId; } public void setPerId(String perId) { this.perId = perId; } @XmlElement(name = "PerName") public String getPerName() { return perName; } public void setPerName(String perName) { this.perName = perName; } @XmlElement(name = "PerAge") public String getPerAge() { return perAge; } public void setPerAge(String perAge) { this.perAge = perAge; } @XmlElement(name = "PerSex") public String getPerSex() { return perSex; } public void setPerSex(String perSex) { this.perSex = perSex; } @XmlElement(name = "PerEmail") public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Person() { // TODO Auto-generated constructor stub } public Person(String perId,String perName,String perAge,String perSex,String email) { this.perId = perId; this.perName = perName; this.perAge = perAge; this.perSex = perSex; this.email = email ; } }
Body类:
package com.insist.objectxml.person; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; /** * 描述:body标头<br> * 作者:liqijing <br> * 修改日期:2015-4-6下午07:34:49 <br> * E-mail: lijinginsistsmile@163.com <br> */ @XmlRootElement(name = "Body") public class Body { private Person person ; @XmlElement(name = "Person") public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } }
commons-lang3-3.1.jar
slf4j-api-1.7.5-sources.jar
slf4j-api-1.7.5.jar
很高兴与你们分享:
希望对需要实现
对象转XML或XML转对象的朋友们有帮助!
谢谢!