上次遗留下来的XMLUtil的问题

·在上周留下了一个关于XMLUtil的问题,问题大概是这样的,需要通过读取一个XML文件,然后在内存中生成一个对应的javaBean。之前写的那个很是糟糕,照着一个XML去写了一个"Util",拓展性,可维护性几乎为0,所有的东西全都写死,完全就写了一个"不伦不类"的"Util",很是郁闷,点击查看之前的代码,所以痛定思痛,打算在本周对上次的Util进行重写,一直拖到今天才花了几个小时写好,不得不感叹我的拖延至之严重!

·下面贴出代码,先是两个实体类

Student(学生类)

package com.taoyuan.entity.custom;

/**
 * @ClassName: Student
 * @Description: TODO Student实体类设计
 * @author: Han
 * @date: 2016-3-31 下午4:54:04
 */
public class Student {

    private int id;
    private String name;

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {

        return "this student`s id is " + this.id + " and name is " + this.name;
    }
}

Class(班级类)可以明显看到两个类是关联关系,在Class类中含有一个Student的集合

package com.taoyuan.entity.custom;

import java.util.List;

/**
 * @ClassName: Class
 * @Description: TODO Class班级实体类设计
 * @author: Han
 * @date: 2016-3-31 下午4:58:21
 */
public class Class {

    private int id;
    private String className;
    private List<Student> student;

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getClassName() {
        return className;
    }
    public void setClassName(String className) {
        this.className = className;
    }
    public List<Student> getStudents() {
        return student;
    }
    public void setStudents(List<Student> student) {
        this.student = student;
    }

    @Override
    public String toString() {

        return "This class`s id is " + this.id + " and name is " + this.className
                + "\t\nit`s students are " + this.student;
    }
}

XML文件

<?xml version="1.0" encoding="UTF-8"?>
<Entity>
    <Class classPath="com.taoyuan.entity.custom.Class">

        <Int name="id">1</Int>
        <String name="className">软件工程</String>
        <Student name="student" type="list">

            <!-- Student数组 -->
            <Student classPath="com.taoyuan.entity.custom.Student">
                <Int name="id">1</Int>
                <String name="name">李明</String>
            </Student>
            <Student  classPath="com.taoyuan.entity.custom.Student">
                <Int name="id">2</Int>
                <String name="name">狗蛋</String>
            </Student>
        </Student>
    </Class>
</Entity>

XMLUtil利用反射,递归等实现的Util,较之前有了很大的改动,再也不用对着一个Util狂改,把通用性将到了0...现在只需要修改XML和Java实体类就可以了

package com.taoyuan.utils;

import java.io.File;
import java.io.FileNotFoundException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
 * @ClassName: XMLUtil
 * @Description: TODO XML工具类
 * @author: Han
 * @date: 2016-3-22 下午3:09:03
 */
public class XMLUtil {

    /**
     * @Title: toEntity
     * @Description: TODO 将XML文件转换为一个entity
     * @param xmlPath
     * @return
     * @throws Exception
     * @return: Object
     */
    public static Object toEntity(String xmlPath) throws Exception{

        //初始化,将XML文件读入内存,生成Document
        Document _document = init(xmlPath);

        //获取根目录节点
        Element _rootEle = _document.getRootElement();
        String _rootName = "";

        if(_rootEle != null){

            //根目录节点名字
            _rootName = _rootEle.getName();
        }

        if(!_rootName.equals("Entity")){

            throw new Exception("请确认根节点名字是否为Entity");
        }

        List<Element> elements = _rootEle.elements();

        //在Entity节点中无子节点
        if(elements.size() == 0){

            return null;
        }

        return getEntity(elements.get(0));
    }

    /**
     * 获取根据节点Element获取对应的Entity
     * @param element
     * @return
     * @throws ClassNotFoundException
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    @SuppressWarnings("rawtypes")
    private static Object getEntity(Element element)
            throws ClassNotFoundException, InstantiationException,
            IllegalAccessException {

        //获取classPath
        String _classPath = element.attributeValue("classPath");

        //获取Class的字节码文件
        Class _clazz = Class.forName(_classPath);
        //根据字节码文件进行实例化
        Object _object = _clazz.newInstance();

        Field[] _fields = _clazz.getDeclaredFields();

        setMember(_object, element, _fields);

        return _object;
    }

    /**
     * 设置成员变量
     * @param object
     * @param element
     * @param fields 成员变量数组
     */
    private static void setMember(Object object, Element element, Field[] fields) {

        //获取当前Element获得的子节点迭代器
        Iterator<Element> _elements = element.elementIterator();
        while(_elements.hasNext()){

            Element _childElement = _elements.next();

            //当前正在设置的成员变量
            Field _field = null;
            //获取变量类型
            String _type = _childElement.getName();

            //获取变量名
            String _name = _childElement.attributeValue("name");
            //获取变量值
            String _value = _childElement.getTextTrim();

            //找到当前正在设置的成员变量
            for(int i = 0;i < fields.length;i ++ ){

                if(fields[i].getName().equals(_name)){

                    _field = fields[i];
                    break;
                }
            }

            if(_field == null){

                throw new RuntimeException("没找到该成员变量" + _name);
            }

            //此时可以访问私有成员变量
            _field.setAccessible(true);

            if(!setBaseTypeMember(object, _field, _type, _value)){

                //当前成员变量不是基本类型,则为引用类型成员变量
                setReferenceTypeMember(_childElement, object,  _field);
            }
        }
    }

    /**
     * 设置引用类型成员变量
     * @param element
     * @param object
     * @param field
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    private static void setReferenceTypeMember(Element element, Object object,  Field field) {

        try {
            //若为list,则表示当前元素为一个list集合
            String _memberType = element.attributeValue("type");

            if(_memberType.equals("list")){

                List _list = new ArrayList();

                Iterator<Element> _iterator = element.elementIterator();
                while(_iterator.hasNext()){

                    Element _childEle = _iterator.next();

                    //递归获取该元素,并加入集合中
                    Object _entity = getEntity(_childEle);
                    _list.add(_entity);
                }

                field.set(object, _list);
                return;
            }

            //单元素的引用类型
            Object _entity = getEntity(element);
            field.set(object, _entity);
        } catch (Exception e) {

            throw new RuntimeException(e);
        }
    }

    /**
     * 设置基本类型成员变量
     * @param object
     * @param field
     * @param type
     * @param value
     * @return
     */
    private static boolean setBaseTypeMember(Object object, Field field,
            String type, String value) {

        try {
            if(type.equals("Int")){

                //int型成员变量
                field.setInt(object, Integer.parseInt(value));
            }else if(type.equals("Double")){

                //double型成员变量
                field.setDouble(object, Double.parseDouble(value));
            }else if(type.equals("Float")){

                //float型成员变量
                field.setFloat(object, Float.parseFloat(value));
            }else if(type.equals("Long")){

                //long型成员变量
                field.setLong(object, Long.parseLong(value));
            }else if(type.equals("Char")){

                //char型成员变量
                field.setChar(object, value.charAt(0));
            }else if(type.equals("String")){

                //string型成员变量
                field.set(object, value);
            }else{

                return false;
            }
        } catch (Exception e) {

            throw new RuntimeException(e);
        }

        return true;
    }

    /**
     * @Title: init
     * @Description: TODO 初始化,将XML读入内存
     * @param xmlPath
     * @return Document节点
     * @throws FileNotFoundException
     * @return: Document
     */
    private static Document init(String xmlPath) throws FileNotFoundException {

        //获取XML文件路径.是根据当前classPath去寻找,例如文件a.xml是放在根目录下,则需要输入的路径便是a.xml
        //还有另外一种方法是通过class.getResource("/" + xmlPath)效果是一样的
        //关于java中的路径问题还是没有搞得很清楚,下来还需要多看
        String _filePath = XMLUtil.class.getClassLoader().getResource(xmlPath).getPath();

        File _file = new File(_filePath);

        //如果文件存在
        if(_file.exists()){

            //利用dom4j返回该XML的document
            SAXReader _reader = new SAXReader();

            try {

                Document _document = _reader.read(_file);

                return _document;

            } catch (DocumentException e) {

                e.printStackTrace();
            }
        }else{

            throw new FileNotFoundException("您输入的XML文件地址未查到");
        }

        return null;
    }

}

测试方法

    @Test
    public void testXMLUtil() throws Exception{

        System.out.println(XMLUtil.toEntity("Class.xml"));
    }

结果输出

Ok,测试成功

·总结一下:

1.下回再也不写那么逗的Util了,每次写Util之前先思考思考如何才能写成一个自己以后还能用到的真正的工具类。

2.对于这个版本自己还是有一些不满意的地方,每个成员变量我都是在XML文件里面声明了它的类型,比如<String ...>,既然我都已经通过反射拿到了成员变量的数组,为什么不用成员变量对象去判断它的类型呢??这个是可以改进的地方。

3.这次变量命名和注释相较于上一次已经有了很大的进步,自己还是比较满意的。

4.有什么理由可以不努力呢??哈哈

时间: 2024-10-08 21:06:46

上次遗留下来的XMLUtil的问题的相关文章

Day35:基于UDO的套接字、粘包问题

一.基于UDP的套接字 UDP服务端 ss = socket() #创建一个服务器的套接字 ss.bind() #绑定服务器套接字 inf_loop: #服务器无限循环 cs = ss.recvfrom()/ss.sendto() # 对话(接收与发送) ss.close() # 关闭服务器套接字 UDP客户端 cs = socket() # 创建客户套接字 comm_loop: # 通讯循环 cs.sendto()/cs.recvfrom() # 对话(发送/接收) cs.close() #

【Python3之socket编程】

一.socket的定义 Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议.所以,我们无需深入理解tcp/udp协议,socket已经为我们封装好了,我们只需要遵循socket的规定去编程,写出的程序自然就是遵循tcp/udp标准的. 补充:也有人将socket说成ip+port,ip是用来

socket 套接字

套接字基础 c/s架构 client ---------internet------------serverserver端: 力求一直提供服务 要绑定一个唯一的地址,让客户端能够明确的找到 客户端/服务器基于网络进行通信,所以要遵询互联网协议ios五层协议:图 TCP/IP协议族包括传输层.网络层.链路层tcp协议传输数据: 以太网头 + IP头 + tcp头 + 数据udp协议传输数据: 以太网头 + IP头 + udp头 + 数据 socket是什么:定义:源IP地址和目的IP地址以及源端口

Python开发基础-Day24socket套接字基础2

基于UDP的socket 面向无连接的不可靠数据传输,可以没有服务器端,只不过没有服务器端,发送的数据会被直接丢弃,并不能到达服务器端 1 #客户端 2 import socket 3 ip_port=('127.0.0.1',8080) 4 BUFSIZE=1024 5 sock_client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #SOCK_DGRAM就是UDP 6 while True: 7 msg=input('>>').str

(七)

还是上次遗留下的空指针问题 明明是对的非说有空指针 今天还出现卡死的情况 感觉越来越糟 现在回过头看之前的代码有点乱 明天开始重新把类 理一下 提高拓展性 今天从下午找到晚上还是没有什么结果 好气 还是得总头到尾自己过一遍 一点也不要想着用现成的 加油哇

Python基础第24天

第五模块:网络编程     一:C/S架构 即C/S架构,包括 1.硬件C/S架构(打印机) 2.软件C/S架构(web服务) 二:socket和互联网协议 1.首先:本节课程的目标就是教会你如何基于socket编程,来开发一款自己的C/S架构软件 2.其次:C/S架构的软件(软件属于应用层)是基于网络进行通信的 3.然后:网络的核心即一堆协议,协议即标准,你想开发一款基于网络通信的软件,就必须遵循这些标准. TCP/IP协议族包括运输层.网络层.链路层 Socket是应用层与TCP/IP协议族

[转] iOS应用架构谈 网络层设计方案

原文地址:http://casatwy.com/iosying-yong-jia-gou-tan-wang-luo-ceng-she-ji-fang-an.html iOS应用架构谈 开篇 iOS应用架构谈 view层的组织和调用方案 iOS应用架构谈 网络层设计方案 iOS应用架构谈 动态部署方案 iOS应用架构谈 本地持久化方案 前言 网络层在一个App中也是一个不可缺少的部分,工程师们在网络层能够发挥的空间也比较大.另外,苹果对网络请求部分已经做了很好的封装,业界的AFNetworking

Mahout算法调用展示平台2.1

软件版本号: windows7: Tomcat7.JDK7.Spring4.0.2.Struts2.3.Hibernate4.3.myeclipse10.0.easyui:Linux(centos6.5):Hadoop2.4.Mahout1.0.JDK7: 使用Webproject调用Mahout的相关算法,提供监控.查看任务的执行状态. 自建Web项目.项目首页例如以下: 1. 准备 项目能够在http://download.csdn.net/detail/fansy1990/7600427(

python/socket编程之粘包

python/socket编程之粘包 粘包: 只有TCP有尿包现象,UDP永远不会粘包. 首先需要掌握一个socket收发消息的原理 发送端可以是1k,1k的发送数据而接受端的应用程序可以2k,2k的提取数据,当然也有可能是3k或者多k提取数据,也就是说,应用程序是不可见的,因此TCP协议是面来那个流的协议,这也是容易出现粘包的原因而UDP是面向笑死的协议,每个UDP段都是一条消息,应用程序必须以消息为单位提取数据,不能一次提取任一字节的数据,这一点和TCP是很同的.怎样定义消息呢?认为对方一次