package com.test.demo.utils;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
/**
* @description Java 反射工具类
* @author weiyi and Zhoupf
* @date 2018/9/21. 14:45.
* @prj FeatureABC.
*/
public class ReflectUtils {
/** 当前xml标签所处层级数 */
private static int curLayerNum = 0;
/**
* bean 转 xml
* @param bean 待转的bean对象
* @return String xml格式的字符串形式
*/
public static String beanToXml(Object bean) throws IllegalArgumentException, IllegalAccessException {
String root = bean.getClass().getSimpleName();
System.out.println("bean的名字:" + root);
// 进入bean的根标签,当前标签层级数加1
curLayerNum++;
StringBuffer stringBuffer = new StringBuffer();
indentAlign(stringBuffer, curLayerNum);
stringBuffer.append("\n");
List fieldList = ReflectUtils.getFileds(bean);
if (!fieldList.isEmpty()) {
// 进入bean的子标签,当前标签层级数加1
curLayerNum++;
for (Field field : fieldList) {
field.setAccessible(true);
String fieldName = field.getName();
Object value = field.get(bean);
System.out.println("字段的名称:" + fieldName + " 类型:" + field.getType().getName() + " 值:" + value);
if (ReflectUtils.isBaseType(field.getType().getName())) {
// field的类型 是 基本数据 类型
indentAlign(stringBuffer, curLayerNum);
stringBuffer.append("" + value + "" + fieldName + ">\n");
} else if (field.getType().equals(java.util.List.class)
|| field.getType().equals(java.util.Set.class)) {
// field的类型 是 List 或 Set 类型
indentAlign(stringBuffer, curLayerNum);
if (!((Collection>) value).isEmpty()) {
stringBuffer.append("\n");
handleCollectionType((Collection>) value, stringBuffer);
indentAlign(stringBuffer, curLayerNum);
stringBuffer.append("" + fieldName + ">\n");
} else {
stringBuffer.append("" + fieldName + ">\n");
}
} else {
/*
* field的类型 是bean对象 类型 因进入bean的根标签curLayerNum会自加1,导致当前标签层级数比实际标签层级数大1,
* 需要将curLayerNum自减1,符合实际情况
*/
curLayerNum--;
stringBuffer.append(beanToXml(value));
}
}
}
// 退出bean的子标签,当前标签层级数减1,返回到bean的根标签
curLayerNum--;
indentAlign(stringBuffer, curLayerNum);
if(curLayerNum == 1) {
// 是转化bean的根标签,则结束标签不需要换行
stringBuffer.append("" + root + ">");
}else {
stringBuffer.append("" + root + ">\n");
}
return stringBuffer.toString();
}
/**
* 以文本的形式保存bean转xml的数据
* @param xmlString 转化的xml字符串
* @param destName 保存文本的位置,例如:C:/Users/Administrator/Desktop/BeanToXml.txt
* @return true:保存成功 ;false:保存失败
*/
public static boolean saveXMLString(String xmlString , String destName) {
FileWriter fileWriter = null;
try {
fileWriter = new FileWriter("C:/Users/Administrator/Desktop/BeanToXml.txt");
fileWriter.write(xmlString);
System.out.println("保存xml文件成功");
return true;
} catch (IOException e) {
e.printStackTrace();
System.out.println("保存xml文件异常");
return false;
} finally {
if(fileWriter != null) {
try {
fileWriter.flush();
fileWriter.close();
System.out.println("正常关闭输出流");
} catch (IOException e) {
e.printStackTrace();
System.out.println("关闭输出流异常");
}
}
}
}
/**
* 获取对象的成员变量
* @param obj
* @return
*/
public static List getFileds(Object obj) {
// 第一步:获取类对象
Class> clazz = obj.getClass();
List fieldList = new ArrayList<>();
// 当父类为null的时候说明到达了最上层的父类(Object类)
while (clazz != null && !clazz.getName().toLowerCase().equals("java.lang.object")) {
System.out.println("类对象名字:" + clazz.getName());
fieldList.addAll(Arrays.asList(clazz.getDeclaredFields()));
// 得到父类,然后赋给自己
clazz = clazz.getSuperclass();
}
return fieldList;
}
/**
* 判断object是否为基本类型
* @param typeName
* @return
*/
public static boolean isBaseType(String fieldType) {
switch (fieldType) {
case "java.lang.String":
case "java.lang.Integer":
case "java.lang.Byte":
case "java.lang.Long":
case "java.lang.Float":
case "java.lang.Double":
case "java.lang.Short":
case "java.lang.Boolean":
case "java.lang.Character":
case "int":
case "short":
case "byte":
case "char":
case "long":
case "float":
case "double":
case "boolean":
return true;
default:
return false;
}
}
/** 成员变量类型是集合类型,集合类型转xml格式处理 */
private static void handleCollectionType(Collection> obj, StringBuffer xmlString)
throws IllegalArgumentException, IllegalAccessException {
// 进入集合的子标签,当前标签层级数加1
curLayerNum++;
// obj 是 List 或 Set 类型集合
Collection> collection = obj;
Iterator> iterator = collection.iterator();
while (iterator.hasNext()) {
Object value = iterator.next();
if (isBaseType(value.getClass().getName())) {
indentAlign(xmlString, curLayerNum);
// value是基本数据类型对象
xmlString.append("" + value + "\n");
} else {
// value是bean对象,因进入bean的根标签curLayerNum会自加1,导致当前标签层级数比实际标签层级数大1,
// 所以需要将curLayerNum自减1,符合实际情况
curLayerNum--;
xmlString.append(beanToXml(value));
}
}
// 退出集合的子标签,当前标签层级数减1
curLayerNum--;
}
/** xml标签按层级缩进对齐 */
private static void indentAlign(StringBuffer xmlString, int count) {
for (int i = 1; i < count; i++) {
xmlString.append(" ");
}
}
}