基于dom4j的xml映射实体的工具类(java)

基于dom4j的xml映射实体的工具类(java)

工具是基于dom4j,使用反射使实体属性与xml的标签关联,目前兼容List,Map后续更新兼容。
历史更新:

  • 发布-2019-6-22
  • 增加注解@XmlAttr关联实体与xml(解决实体名与xml属性名不相同的情况)-2019-7-12

背景故事:这是个大哥与小弟的团队关系

  • xml文件
<bigbro>
	<name>大哥</name>
    <powder>70</powder>
    <brolist>
        <bro>
            <name>小弟1</name>
            <powder>50</powder>
            <littlebro>
                <name>小小弟1-1</name>
                <powder>45</powder>
            </littlebro>
            <littlebro>
                <name>小小弟1-2</name>
                <powder>45</powder>
            </littlebro>
        </bro>
        <bro>
            <name>小弟2</name>
            <powder>51</powder>
            <littlebro>
                <name>小小弟2-1</name>
                <powder>50</powder>
            </littlebro>
            <littlebro>
                <name>小小弟2-2</name>
                <powder>50</powder>
            </littlebro>
        </bro>
</bigbro>
  • 实体
    1)大哥的实体
import java.util.List;

public class BigBro {
	@XmlAttr("name")
    private String name;
    
    @XmlAttr("power")
    private String power;

	@XmlAttr("brolist")
    private List<Bro> brolist;
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPower() {
        return power;
    }

    public void setPower(String power) {
        this.power = power;
    }

    public List<Bro> getBrolist() {
        return brolist;
    }

    public void setBrolist(List<Bro> brolist) {
        this.brolist = brolist;
    }
}

2)小弟的实体

import java.util.List;

public class Bro {

	@XmlAttr("name")
    private String name;
    
    @XmlAttr("power")
    private String power;

	@XmlAttr("")
    private List<Bro> littlebrolist;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPower() {
        return power;
    }

    public void setPower(String power) {
        this.power = power;
    }

    public List<Bro> getLittlebrolist() {
        return littlebrolist;
    }

    public void setLittlebrolist(List<Bro> littlebrolist) {
        this.littlebrolist = littlebrolist;
    }
}

  • XmlReader代码
import Annotation.XmlAttr;
import Annotation.XmlAttrImplicit;
import entity.RspPerson;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.StringReader;
import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;


public class XmlReader {

    public XmlReader() {
    }

    /**
     *  映射xml到实体
     * @param clazz
     * @param xmlStr
     * @param <T>
     * @return
     */
    public <T> T parseToEntity(Class<T> clazz, String xmlStr) {
        SAXReader reader = new SAXReader();
        reader.setEncoding("GBK");
        Document doc;
        T obj = null;
        try {
            obj = clazz.getDeclaredConstructor().newInstance();
            doc = reader.read(new StringReader(xmlStr));
            Element root = doc.getRootElement();
            handleNode(root, obj);
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return obj;
    }

    /**
     *  处理节点
     * @param element
     * @param t
     * @param <T>
     */
    public  <T> void handleNode(Element element, T t) {
        for (Iterator<Element> it = element.elementIterator(); it.hasNext();) {
            Element child = it.next();
            Field field = null;
            try {
                field = getFieldByAttrName(child.getName(), t);
                if (field == null) {
                    return ;
                }
                PropertyDescriptor descriptor = new PropertyDescriptor(field.getName(), t.getClass());
                Class<?> clazz = Class.forName(field.getType().getTypeName());
                Object childObject = null;
                if (descriptor.getPropertyType().getTypeName().equals("java.util.List")) {
                    childObject = Proxy.newProxyInstance(RspPerson.class.getClassLoader(), new Class[] {clazz}, new MyHandler());
                } else {
                    childObject = Class.forName(field.getType().getTypeName()).getDeclaredConstructor().newInstance();
                }
                Method setMethod = descriptor.getWriteMethod(); //获得set方法
                Type type = field.getGenericType();
                if (type instanceof ParameterizedType) {
                    //带参数类型的属性
                    ParameterizedType pt = (ParameterizedType)type; //获取参数类型
//                    System.out.println("带参数" + type.getTypeName());
                    String paramClassName = pt.getActualTypeArguments()[0].getTypeName(); //获取实体属性的参数类型,如List<A>的A
                    if (childObject instanceof List) {
                        ArrayList childList = new ArrayList();
                        Iterator<Element> childIterator = child.elementIterator();
                        while (childIterator.hasNext()) {
                            Element sonOfElement = childIterator.next();
                            System.out.println(sonOfElement.getName());
                            Object paramObject = Class.forName(paramClassName).getDeclaredConstructor().newInstance();
                            childList.add(paramObject);
                            handleNode(sonOfElement, paramObject);
                        }
                        setMethod.invoke(t, childList);
                    } else if (childObject instanceof HashMap){
                        //HashMap类型属性...
                    }
                } else {
                    //不带参数类型的属性
//                    System.out.println("非带参数" + type.getTypeName());
                    setMethod.invoke(t, child.getData());
                }
            } catch (SecurityException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (IntrospectionException e) {
                e.printStackTrace();
            }
        }
    }

    private <T> Field getFieldByAttrName(String xmlAttrName, T t) {
        for (Field f : t.getClass().getDeclaredFields()) {
            if (f.isAnnotationPresent(XmlAttr.class)) {
                if(f.getAnnotation(XmlAttr.class).value().equals(xmlAttrName)){
                    return f;
                }
            } else if (f.isAnnotationPresent(XmlAttrImplicit.class)) {
                if (f.getAnnotation(XmlAttrImplicit.class).value().equals(xmlAttrName)){
                    return f;
                }
            }
        }
        return null;
    }
}

-MyHandler代码

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.List;

class MyHandler implements InvocationHandler {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return null;
    }
}

-@XmlAttr 注解

package Annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 普通属性,基本数据类型的包装类
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface XmlAttr {
    String value() default "";
}

-@XmlAttrImplicit注解

package Annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 属性为集合接口List,Map等类型
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface XmlAttrImplicit {
    String value() default "";
}

  • 结果
    在这里插入图片描述
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值