自实现 XML 与 对象 间的自动转换

前端之家收集整理的这篇文章主要介绍了自实现 XML 与 对象 间的自动转换前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

在java中,解析、分装xml是一件非常“麻烦”的事。我们常常需要写大量的代理来解析不同的XML文件,然后将解析结果赋值给相关对象,便于更好的使用;或者将相关对象转换成XML格式进行输出。为了减去这繁琐的操作,笔者通过反射、注解的功能来实现 XML 与 JAVA对象 的相互转换。

同时,可能存在协议的变动,某些xml标签可能不在返回,这里也提供通过注解,快速屏蔽bean中某些属性的解析和分装。大大提高了转换的灵活度,以及便于最小程度的改动现有代码

XML ——> bean

@H_301_13@ /** * 解析xml * @param c 目标对象的Class类 * @param parentObj 对象的父类,主要用于将对象set到父类中。即,递归地将c目标对象中的各个属性对象进行set操作,使c目标对象属性值为解析结果。 * @param isCollection 是否是Collection。如果目标对象包含Collection,则定义Class的时候,需要将Collection初始化 * @param element 当前对象的Xml层对应的Element * @return 封装好的c对象实例 * @throws Exception */ @SuppressWarnings({ "rawtypes","unchecked" }) public static Object parseXml(Class c,Object parentObj,boolean isCollection,Element element) throws Exception { Object currentObj = null; Element currentElement = element; if (parentObj == null) { currentObj = c.newInstance(); } else if(isCollection) { currentObj = parentObj; } else { //通过c获取className,并将className对象set到parentObj中 String[] strs = c.getName().split("\\."); strs = strs[strs.length - 1].split("\\$"); String className = strs[strs.length - 1]; element = currentElement.element(className.toUpperCase()); if(element == null) { throw new Exception("parseXml Error. target:" + className + " is not exists"); } currentObj = c.newInstance(); String setMethod = "set" + className.substring(0,1).toUpperCase() + className.substring(1); Method method = parentObj.getClass().getDeclaredMethod(setMethod,c); method.invoke(parentObj,new Object[]{currentObj}); } Field[] fieldArray = c.getDeclaredFields(); for (Field field : fieldArray) { //若属性标示为无需解析,则continue if(field.isAnnotationPresent(XmlTransformAnnotation.class)) { XmlTransformAnnotation xmlAnnotation = (XmlTransformAnnotation)field.getAnnotation(XmlTransformAnnotation.class); String isParse = xmlAnnotation.value(); if(XmlTransformAnnotation.FLASE.equals(isParse)) { continue; } } Class basicType = getBasicType(field.getType()); if (basicType != null) { //属性为基本类型(包括:String、Integer、Byte、Short、Long、Float、Double、Character、Boolean、int、byte、short、long、float、double、char、boolean) //解析属性xml标签,并将解析结果赋值到currentObj中 String setMethod = "set" + field.getName().substring(0,1).toUpperCase() + field.getName().substring(1); Method method = c.getDeclaredMethod(setMethod,field.getType()); Element fieldElement = element.element(field.getName().toUpperCase()); if(fieldElement != null) { String value = fieldElement.getText(); Object fieldObj = basicType.getConstructor(String.class).newInstance(value); method.invoke(currentObj,fieldObj); } else { throw new Exception("parseXml Error. target:" + field.getName() + " is not exists"); } } else { if (isCollection(field.getType())) { //Collection解析 String getMethodStr = "get" + field.getName().substring(0,1).toUpperCase() + field.getName().substring(1); String setMethodStr = "set" + field.getName().substring(0,1).toUpperCase() + field.getName().substring(1); Method getMethod = c.getDeclaredMethod(getMethodStr); Collection collection = getCollectionByClass(field.getType()); Method setMethod = c.getDeclaredMethod(setMethodStr,field.getType()); setMethod.invoke(currentObj,collection); //正式返回类型的type对象。例如:java.util.List<com.bayern.xml.example.entity.req.StaffBindReqBody$Staffs> Type returnType = getMethod.getGenericReturnType(); //ParameterizedType : Comparable<? super T>,Collection符合该类型格式,例如Collection<String>。 if (returnType instanceof ParameterizedType) { ParameterizedType t = (ParameterizedType) returnType; //getActualTypeArguments():返回表示此类型实际类型参数的 Type 对象的数组。 //因为List、Set泛型中只有一个参数,所以直接通过[0]获取。 Type pType = t.getActualTypeArguments()[0]; //Collection的泛型对象 Class pc = Class.forName(((Class) pType).getName()); Method addMethod = field.getType().getDeclaredMethod("add",Object.class); List<Element> elementList = element.elements(field.getName().toUpperCase()); for(Element pcElement : elementList) { Object parameterObj = pc.newInstance(); addMethod.invoke(collection,new Object[]{parameterObj}); parseXml(pc,parameterObj,true,pcElement); } } } else { //对象解析 parseXml(field.getType(),currentObj,false,currentElement); } } } return currentObj; }


bean ——>XML

	/**
	 * 封装xml
	 * @param c 目标对象Class类
	 * @param currentObj 被转换对象
	 * @param flag 是否需要xml头及root标签
	 * @return 解析后的xml
	 * @throws Exception
	 * @throws NoSuchMethodException
	 */
	@SuppressWarnings({ "unchecked","rawtypes" })
	public static String packageXml(Class c,Object currentObj,boolean flag) throws Exception 
	{
		if(currentObj == null) 
		{
			return "";
		}
		StringBuffer xml = new StringBuffer();
		if(flag) 
		{
			xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
			String[] strs = c.getName().split("\\.");
			xml.append("<").append(strs[strs.length-1].toUpperCase()).append(">");
		}
		Field[] fieldArray = c.getDeclaredFields();
		for(Field field : fieldArray) 
		{
			if(field.isAnnotationPresent(XmlTransformAnnotation.class))
			{
				XmlTransformAnnotation xmlAnnotation = field.getAnnotation(XmlTransformAnnotation.class);
				if(XmlTransformAnnotation.FLASE.equals(xmlAnnotation.value()))
				{
					continue;
				}
			}
			
			Class basicType = getBasicType(field.getType());
			if (basicType != null)
			{
				//分装基本类型(包括:String、Integer、Byte、Short、Long、Float、Double、Character、Boolean、int、byte、short、long、float、double、char、boolean)
				
				xml.append("<").append(field.getName().toUpperCase()).append(">");
				String setMethod = "get" + field.getName().substring(0,1).toUpperCase() + field.getName().substring(1);
				Method method = c.getDeclaredMethod(setMethod);
				String value = method.invoke(currentObj) != null ? method.invoke(currentObj).toString() : "";
				xml.append(value);
				xml.append("</").append(field.getName().toUpperCase()).append(">");
			}
			else
			{
				if (isCollection(field.getType()))
				{
					//分装Collection
					
					String getMethod = "get" + field.getName().substring(0,1).toUpperCase() + field.getName().substring(1);
					Method method = c.getDeclaredMethod(getMethod);
					Object collectionObj = method.invoke(currentObj);
					Type returnType = method.getGenericReturnType();
					if (returnType instanceof ParameterizedType)
					{
						ParameterizedType t = (ParameterizedType) returnType;
						Type pType = t.getActualTypeArguments()[0];
						Class pc = Class.forName(((Class) pType).getName());
						
						Collection collection = (Collection)collectionObj;
						if(collection != null) 
						{
							for(Iterator iter = collection.iterator(); iter.hasNext();)
							{
								Object subObj = iter.next();
								xml.append("<").append(field.getName().toUpperCase()).append(">");
								String subXml = packageXml(pc,subObj,false);
								xml.append(subXml);
								xml.append("</").append(field.getName().toUpperCase()).append(">");
							}
						}
							
					}
				}
				else
				{
					//分装对象
					
					String[] strs = field.getName().split("\\.");
					strs = strs[strs.length - 1].split("\\$");
					String className = strs[strs.length - 1];
					xml.append("<").append(className.toUpperCase()).append(">");
					String getMethod = "get" + className.substring(0,1).toUpperCase() + className.substring(1);
					Method method = c.getDeclaredMethod(getMethod);
					Object subObj = method.invoke(currentObj);
					String subXml = packageXml(field.getType(),false);
					xml.append(subXml);
					xml.append("</").append(className.toUpperCase()).append(">");
				}
			}
		
			
		}
		if(flag) 
		{
			String[] strs = c.getName().split("\\.");
			xml.append("</").append(strs[strs.length-1].toUpperCase()).append(">");
		}
		return xml.toString();
	}


辅助方法

	/**
	 * 判断Class的类型是不是基本类型。基本类型包括:String、Integer、Byte、Short、Long、Float、Double、Character、Boolean、int、byte、short、long、float、double、char、boolean
	 * 如果是基本类型则返回对应的Class,否则返回null
	 * @param type
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	private static Class getBasicType(Class type) 
	{
		if (String.class.equals(type))
		{
			return String.class;
		}
		else if (Integer.class.equals(type))
		{
			return Integer.class;
		}
		else if (Byte.class.equals(type))
		{
			return Byte.class;
		}
		else if (Short.class.equals(type))
		{
			return Short.class;
		}
		else if (Long.class.equals(type))
		{
			return Long.class;
		}
		else if (Float.class.equals(type))
		{
			return Float.class;
		}
		else if (Double.class.equals(type))
		{
			return Double.class;
		}
		else if (Character.class.equals(type))
		{
			return Character.class;
		}
		else if (Boolean.class.equals(type))
		{
			return Boolean.class;
		}
		else if(type.getName().equals(Constant.BASIC_TYPE_BOOLEAN))
		{
			return Boolean.class;
		}
		else if(type.getName().equals(Constant.BASIC_TYPE_BYTE))
		{
			return Byte.class;
		}
		else if(type.getName().equals(Constant.BASIC_TYPE_CHAR))
		{
			return Character.class;
		}
		else if(type.getName().equals(Constant.BASIC_TYPE_DOUBLE))
		{
			return Double.class;
		}
		else if(type.getName().equals(Constant.BASIC_TYPE_FLOAT))
		{
			return Float.class;
		}
		else if(type.getName().equals(Constant.BASIC_TYPE_INT))
		{
			return Integer.class;
		}
		else if(type.getName().equals(Constant.BASIC_TYPE_SHORT))
		{
			return Short.class;
		}
		return null;
	}
	
	/**
	 * 判断Class是不是Collection类型,这里之判断了List、Set两种
	 * @param type
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("rawtypes")
	private static boolean isCollection(Class type) throws Exception
	{
		//isAssignableFrom(Class<?> cls)判定此 Class 对象所表示的类或接口与指定的 Class 参数所表示的类或接口是否相同,或是否是其超类或超接口。
		if(List.class.isAssignableFrom(type)) {
			return true;
		} else if(Set.class.isAssignableFrom(type)) {
			return true;
		}
		return false;
	}
	
	/**
	 * 根据class获取Collection
	 * @param type Collection对应的Class
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("rawtypes")
	private static Collection getCollectionByClass(Class type) throws Exception 
	{
		Collection collection = null;
		if(type.isInterface()) {
			List list = new ArrayList();
			Set set = new HashSet();
			
			//isInstance(Object obj)判定指定的 Object 是否与此 Class 所表示的对象赋值兼容。
			if (type.isInstance(list))
			{
				collection = list;
			}
			else if(type.isInstance(set))
			{
				collection = set;
			}
		}else {
			collection = (Collection)type.newInstance();
		}
		
		return collection;
	}


完整代码链接https://git.oschina.net/bayern.com/XmlTransformFrame.git

猜你在找的XML相关文章