构建
public class SmartXmlBuilderUtil {
/**
* 需要特殊处理Bo
*/
private static Map<String,String> specialDis = new HashMap<String,String>();
static
{
specialDis.put("EmployeeRequisition", "DOCUMENTS");
specialDis.put("PurchaseRequisition", "DOCUMENTS");
}
/**
* 智能构造XML文档
*
* @param obj
* 要生成XML的实体对象
* @param element
* 节点元素
* @return 生成的XML文档
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InstantiationException
* @throws Exception
*/
public static void objectRecursion(Object obj, Element element,String defNodeName)
throws IllegalArgumentException, IllegalAccessException
{
Class<? extends Object> classType = obj.getClass();
Field[] fileds = classType.getDeclaredFields();// 得到实体的所有属性
//String entityName = classType.getSimpleName();
if( null != defNodeName)
element = element.addElement(defNodeName);
//Element entityElement = element;
Element cellElement = null;
for (int i = 0; i < fileds.length; i++) {
Field field = fileds[i];
// 设置private的属性值可以读取
field.setAccessible(true);
String fieldName = field.getName();
cellElement = element.addElement(fieldName.toUpperCase());
Object value = field.get(obj);
if (value != null)
{
if (value instanceof Date)
{
if (!(value instanceof Time)) {
cellElement.addText(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(value));
} else {
cellElement.addText(new SimpleDateFormat("HH:mm:ss").format(value));
}
}
else if (value instanceof List<?>) // 若为list类型装换为一个以‘,’分隔的字符串
{
StringBuffer tempString = new StringBuffer();
List<?> tempList = (List<?>) value;
for (int j = 0; j < tempList.size(); j++) {
tempString.append(tempList.get(j) + ",");
}
cellElement.addText(tempString.toString());
}
else if (value instanceof Set<?>)
{
Set<?> tempSet = (Set<?>) value;
Element setElement = null;
if(!tempSet.iterator().hasNext())
return;
String enementName = tempSet.iterator().next().getClass().getSimpleName();
if(null != specialDis.get(enementName))
{
enementName = specialDis.get(enementName);
}
setElement = element.addElement(enementName.toUpperCase());
// 此方法只处理自己定义的类型,若为元数据类型或者其他更复杂的set类型请自己进行处理
for (Iterator<?> iter = tempSet.iterator(); iter.hasNext();) {
Object object = (Object) iter.next();
objectRecursion(object,setElement,"item");
}
cellElement.detach();// 删除具有set属性的元素,因现在它已经变成一个节点
}
else
{
cellElement.addText(value.toString());
}
}
else
{
cellElement.addText("");
}
}
}
}
解析
public class SmartParsersXmlUtil {
public static final String SYS_DATE_FORMAT = "yyyy-MM-dd";
/**
* 解析XML获取,转换成对应的CLASS
*
*
* @param beanClass Class (需要转换成某个实体的Class)
* @param filepath XML文件名
* @return 单个CLASS对象
* @throws Exception 抛出
*/
public static Object parserXMLToClass(String filePath, Class<?> beanClass)
throws Exception {
File inputXml = new File(filePath);
Object bean = parserXMLToClass(inputXml,beanClass);
return bean;
}
/**
* 解析XML获取,转换成对应的CLASS
*
*
* @param beanClass Class(需要转换成某个实体的Class)
* @param file XML文件
* @return 单个CLASS对象
* @throws InstantiationException 抛出
* @throws IllegalAccessException 抛出
*/
public static Object parserXMLToClass( File file,Class<?> beanClass)throws InstantiationException, IllegalAccessException {
Object bean = beanClass.newInstance();
Long startTime = System.currentTimeMillis();
SAXReader saxReader = new SAXReader();
List<String> fields = captureClassFields(beanClass);
try {
Document document = saxReader.read(file);
Element element = document.getRootElement();
BeanInfo beanInfo = Introspector.getBeanInfo(beanClass);
PropertyDescriptor[] pDesc = beanInfo.getPropertyDescriptors();
System.out.println(element.getName());
parserXMLToClass(bean, element, pDesc,fields);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("#----Time consuming:\t"+(System.currentTimeMillis() - startTime));
return bean;
}
/**
* 通过解析XML来获取实体LIST
*
*
* @param filePath 文件路径
* @param beanClass 实体类型 (需要转换成某个实体的Class)
* @param parentNode 所在xml父节点
* @return Class集
* @throws Exception 抛出
*/
public static List<?> parserXMLByClassList(String filePath,Class<?> beanClass) throws Exception {
File inputXml = new File(filePath);
return parserXMLByClassList(inputXml, beanClass);
}
/**
* 通过解析XML来获取实体LIST<CLASS>
*
*
*
* @param file XML文件
* @param beanClass 实体类型 (需要转换成某个实体的Class)
* @param parentNode 所在xml父节点
* @return Class集
* @throws Exception 抛出
*/
public static List<?> parserXMLByClassList(File file,Class<?> beanClass) throws Exception {
Long startTime = System.currentTimeMillis();
List<Object> beanList = new ArrayList<Object>();
//Class<? extends Object> beanClass = Class.forName(type.getName());
SAXReader saxReader = new SAXReader();
List<String> fields = captureClassFields(beanClass);
try {
BeanInfo beanInfo = Introspector.getBeanInfo(beanClass);
PropertyDescriptor[] desc = beanInfo.getPropertyDescriptors();
Document document = saxReader.read(file);
Element element = document.getRootElement();
//System.out.println(element.getName());
parsersXmlToClassList(beanClass, beanList, desc, fields,element);
System.out.println("#----Time consuming:\t"+(System.currentTimeMillis() - startTime));
} catch (Exception e) {
e.printStackTrace();
}
return beanList;
}
//解析XML文件CLASS
private static void parserXMLToClass(Object bean,Element element, PropertyDescriptor[] pDesc,List<String> fields)
throws IllegalAccessException, InvocationTargetException, NoSuchFieldException, ParseException {
for (PropertyDescriptor propertyDescriptor : pDesc) {
String propertyName = propertyDescriptor.getName();
for (Iterator<?> iterator = element.elementIterator(); iterator.hasNext();) {
Element tempElement = (Element) iterator.next();
String nodeName = tempElement.getName();
if(nodeName.equals(bean.getClass().getSimpleName()))
{
if (fields.contains(propertyName)) {
Method readMethod = propertyDescriptor.getWriteMethod();
//所有的属性节点都是大写,SO 需要 toUpperCase
String value = tempElement.elementText(propertyName.toUpperCase());
Object result = correctFields(captureFieldType(bean.getClass(), propertyName), value);
//System.out.println("propertyName=" + propertyName + "\tvalue = " + value);
if (value != null) {
readMethod.invoke(bean, result);
}
}
}
else
{
for (Iterator<?> ite = element.elementIterator(); ite.hasNext();) {
Element ele = (Element) ite.next();
parserXMLToClass(bean, ele, pDesc,fields);
}
}
}
}
}
//解析XML文件TOLIST<CLASS>
private static void parsersXmlToClassList(Class<?> beanClass, List<Object> beanList,PropertyDescriptor[] desc, List<String> field, Element element)
throws InstantiationException, IllegalAccessException,
NoSuchFieldException, ParseException, InvocationTargetException {
//类名对应的节点全部大写,SO 需要 toUpperCase
if (!beanClass.newInstance().getClass().getSimpleName().toUpperCase().equals(element.getName())) {
for (Iterator<?> temp = element.elementIterator(); temp.hasNext();) {
Element elm = (Element) temp.next();
//System.out.println(elm.getName());
parsersXmlToClassList(beanClass, beanList, desc,field, elm);
}
}
else
{
for (Iterator<?> temp = element.elementIterator(); temp.hasNext();) {
Element elm = (Element) temp.next();
Object bean = beanClass.newInstance();
for (PropertyDescriptor propertyDescriptor : desc) {
String propertyName = propertyDescriptor.getName();
if (field.contains(propertyName)) {
Method readMethod = propertyDescriptor.getWriteMethod();
//所有的属性节点都是大写,SO 需要 toUpperCase
String value = elm.elementText(propertyName.toUpperCase());
/*-----矫正字段类型START-----*/
Object result = correctFields(captureFieldType(beanClass, propertyName), value);
/*-----矫正字段类型END-----*/
//System.out.println("propertyName=" + propertyName+ "\tvalue = " + value);
if (value != null) {
readMethod.invoke(bean, result);
}
}
}
beanList.add(bean);
}
return;
}
}
//矫正字段类型 ----- 后续跟进补全
private static Object correctFields(Class<?> c, String value) throws NoSuchFieldException,
ParseException {
Object result = value;
if(c == String.class || result== null)
{
return result;
}
else if (c == Double.class) {
result = Double.valueOf(value);
}
else if (c == Long.class) {
result = Long.valueOf(value);
}
else if (c == Timestamp.class) {
SimpleDateFormat ft = new SimpleDateFormat(SYS_DATE_FORMAT);
Date d = (Date) ft.parse(value);
Timestamp ts = new Timestamp(d.getTime());
result = ts;
}
return result;
}
//捕获字段类型
private static Class<?> captureFieldType(Class<? extends Object> beanClass,String propName) throws NoSuchFieldException {
Field f = beanClass.getDeclaredField(propName);
Class<?> c = f.getType();
return c;
}
//捕获类所有字段
private static List<String> captureClassFields(Class<?> beanClass) {
List<String>fields = new ArrayList<String>();
Field[] fs = beanClass.getDeclaredFields();
for (Field f : fs) {
fields.add(f.getName());
}
return fields;
}
}