11_XML & 反射

作者: AndroidCat | 来源:发表于2017-06-06 22:57 被阅读0次
目标
  • 使用反射模拟servlet执行
XML
  • 在servlet中,为了灵活实现不同的路径执行不同的资源,我们需要使用xml进行配置
  • 为了限定XML的内容,我们需要使用xml的约束(DTD约束或schema约束)
  • 为了获得xml的内容,需要使用dom4j进行操作
XML简介
  • xml:可扩展标记语言
  • xml使用的是1.0版本,因为1.1发布了基本没人用(不向下兼容),所以一直都是用1.0版本
  • xml一开始作数据传输,后来数据传输json应用更广泛,现在xml多用于配置文件
  • xml区分大小写,需要有根元素
  • xml属性值必须要有引号
XML语法
  • 文档声明
    • <?xml version="1.0" encoding="utf-8"?>
DTD约束
  • Document Type Definition
  • 开发中我们很少自己写DTD文档,都是根据(框架)给定的DTD文件,自己写配置文件(借助工具来实现)
  • DTD文件:
<?xml version="1.0" encoding="UTF-8"?>
<!--
    模拟servlet2.3规范,如果开发人员需要在xml使用当前DTD约束,必须包括DOCTYPE。
    格式如下:
    <!DOCTYPE web-app SYSTEM "web-app_2_3.dtd">
-->
<!ELEMENT web-app (servlet*,servlet-mapping* , welcome-file-list?) >
<!ELEMENT servlet (servlet-name,description?,(servlet-class|jsp-file))>
<!ELEMENT servlet-mapping (servlet-name,url-pattern+) >
<!ELEMENT servlet-name (#PCDATA)>
<!ELEMENT servlet-class (#PCDATA)>
<!ELEMENT url-pattern (#PCDATA)>
<!ELEMENT description (#PCDATA)>
<!ELEMENT jsp-file (#PCDATA)>

<!ELEMENT welcome-file-list (welcome-file+)>
<!ELEMENT welcome-file (#PCDATA)>

<!ATTLIST web-app version CDATA #IMPLIED>
  • 通过工具生成的xml文档
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app SYSTEM "web-app_2_3.dtd">
<web-app version="1.0">
    <servlet>
        <servlet-name></servlet-name>
        <servlet-class></servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name></servlet-name>
        <url-pattern></url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file></welcome-file>
    </welcome-file-list>
</web-app>
shema约束
  • scheam是新的xml文档约束

  • schema比DTD更加强大,是DTD的替代

  • schema本身也是xml文档,但scheam的扩展名为xsd

  • schema功能更加强大,数据类型更加完善

  • schema支持命名空间

  • schema文档

<?xml version="1.0" encoding="UTF-8"?>
<!-- 
    模拟servlet2.5规范,如果开发人员需要在xml使用当前Schema约束,必须包括指定命名空间。
    格式如下:
    <web-app xmlns="http://www.example.org/web-app_2_5" 
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://www.example.org/web-app_2_5 web-app_2_5.xsd"
            version="2.5">
-->
<xsd:schema xmlns="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="http://www.example.org/web-app_2_5"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:tns="http://www.example.org/web-app_2_5" 
    elementFormDefault="qualified">
    
    <xsd:element name="web-app">
        <xsd:complexType>
            <xsd:choice minOccurs="0" maxOccurs="unbounded">
                <xsd:element name="servlet">
                    <xsd:complexType>
                        <xsd:sequence>
                            <xsd:element name="servlet-name"></xsd:element>
                            <xsd:element name="servlet-class"></xsd:element>
                        </xsd:sequence>
                    </xsd:complexType>
                </xsd:element>
                <xsd:element name="servlet-mapping">
                    <xsd:complexType>
                        <xsd:sequence>
                            <xsd:element name="servlet-name"></xsd:element>
                            <xsd:element name="url-pattern" maxOccurs="unbounded"></xsd:element>
                        </xsd:sequence>
                    </xsd:complexType>
                </xsd:element>
                <xsd:element name="welcome-file-list">
                    <xsd:complexType>
                        <xsd:sequence>
                            <xsd:element name="welcome-file" maxOccurs="unbounded"></xsd:element>
                        </xsd:sequence>
                    </xsd:complexType>
                </xsd:element>
            </xsd:choice>
            <xsd:attribute name="version" type="double" use="optional"></xsd:attribute>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>
  • 根据约束生成的xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://www.example.org/web-app_2_5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.example.org/web-app_2_5 web-app_2_5.xsd"
    version="2.5">

    <servlet>
        <servlet-name>helloServlet</servlet-name>
        <servlet-class>xxxxxxxxxx</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>helloServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>
xml解析
  • html解析的方式
    1. DOM:整个xml文档加载到内存,解析成一个document对象
      • 优点:元素与元素之间保留结构关系,能够进行增删改查操作
      • 缺点:xml文件过大会导致内存溢出
    2. SAX:逐行解析xml文件
      • 优点:解析速度快,可以处理大文件
      • 缺点:不能进行增删改查操作
    3. PULL:Android内置的解析方式,类似于SAX解析
  • 使用dom4j解析xml文件
    • 需要使用dom4j就需要导入相应的jar包
    • dom4j的核心类是SaxReader,读取xml文件后获得Document对象,通过Document获取根元素后进行操作
    • SaxReader:
      • read(...):加载xml文档
    • Document:
      • getRootElement():获取根元素
    • Element:
      • elements(...):获取自定名称的所有元素
      • element(...):获取指定名称的第一个元素
      • getName():获取当前元素的元素名
      • attribeValue():获取指定属性的属性值
      • elementText(...):获取指定元素的问本值
      • getText():获取当前元素的文本内容
public void testReadWebXML() {
    try {
        // 1.获取解析器
        SAXReader saxReader = new SAXReader();
        // 2.获得document文档对象
        Document doc = saxReader.read("src/cn/itheima/xml/schema/web.xml");
        // 3.获取根元素
        Element rootElement = doc.getRootElement();
        // System.out.println(rootElement.getName());//获取根元素的名称
        // System.out.println(rootElement.attributeValue("version"));//获取根元素中的属性值
        // 4.获取根元素下的子元素
        List<Element> childElements = rootElement.elements();
        // 5.遍历子元素
        for (Element element : childElements) {
            //6.判断元素名称为servlet的元素
            if ("servlet".equals(element.getName())) {
                //7.获取servlet-name元素
                Element servletName = element.element("servlet-name");
                //8.获取servlet-class元素
                Element servletClass = element.element("servlet-class");
                System.out.println(servletName.getText());
                System.out.println(servletClass.getText());
            }
        }
    } catch (DocumentException e) {
        e.printStackTrace();
    }
}
反射
  • 通过接口来解耦
  • 获得Class对象
    1. Class.forName("已知类的完整路径名");
    2. 已知类.class
    3. 已知对象.getClass()
  • 使用默认的构造方法
    • newInstance()
  • Constructor对象
    • Constructor对象是构造方法的描述对象
    • 获取构造方法对象:
      • Constructor<T> getConstructor(Class<T> ...parameterTypes),可变参数用于确定参数列表
      • Constructor<T> getDeclaredConstructor(Class<T> ...parameterTypes)
      • newInstance(Object...initargs):可变参数用于确定实际参数列表
  • Method对象
    • Method对象是普通方法的描述对象
    • 获取方法:
      • Method getMethod(String name,Class<T>...params)
      • Method getDelcaredMethod(String name,Class<T>...params)
      • Ojbect invoke(Object obj,Object...args)
  • Filre对象
    • 字段描述对象
    • 获得方法:
      • File getFile(String name)
      • File getDeclaredFile(String name)
    • 操作:
      • Object get(Object obj)
      • void set(Object obj,Object...value)
public class TestMyServlet2 {
    //8.创建一个map集合
    private HashMap<String, String> data = new HashMap<String,String>();
    
    @Before
    public void testReadWEBXml(){
        try {
            //1.创建解析器对象
            SAXReader saxReader = new SAXReader();
            //2.使用解析器加载web.xml文件得到document对象
            Document document = saxReader.read("src/cn/itheima/web/servlet1/web.xml");
            //3.获取根元素节点
            Element rootElement = document.getRootElement();
            //4.获取子节点(servlet和servlet-mapping)
            List<Element> childElements = rootElement.elements();
            //5.遍历
            for (Element element : childElements) {
                //6.判断元素的名称为servlet的元素节点
                if("servlet".equals(element.getName())){
                    //7.分别获取servlet元素节点的servlet-name和servlet-class的值
                    String servletName = element.element("servlet-name").getText();
                    String servletClass = element.element("servlet-class").getText();
                    /*System.out.println(servletName);
                    System.out.println(servletClass);*/
                    data.put(servletName, servletClass);
                }
                //9.判断元素的名称为servlet-mapping的元素节点
                if("servlet-mapping".equals(element.getName())){
                    //10.分别获取servlet元素节点的servlet-name和servlet-class的值
                    String servletName = element.element("servlet-name").getText();
                    String urlPattern = element.element("url-pattern").getText();
                    //11.将servletName作为key来获取servletClass的值
                    String servletClass = data.get(servletName);
                    //12.将url-pattern作为key,servletClass作为value存到map中去
                    data.put(urlPattern, servletClass);
                    //13.移除servletName
                    data.remove(servletName);
                }
            }
            //System.out.println(data);
            
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }
    
    @Test
    public void testMyServlet(){
        try {
            //1.模拟在浏览器输入一个url
            String url1 = "/myServlet2";
            //2.将urlPattern作为key来获取servletClass
            String className = data.get(url1);
            //3.通过servletClass获取字节码文件
            Class clazz = Class.forName(className);
            //4.通过字节码文件创建实例对象
            Object obj = clazz.newInstance();
            //5.通过字节码文件获取方法(两个参数:第一个是方法名称;第二个参数是方法的参数)
            Method method = clazz.getMethod("service", null);
            //6.调用invoke方法执行实例对象里面的方法(前面写的方法init)【两个参数:第一个是调用方法的实例对象,第二个是方法的实参】
            method.invoke(obj, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

相关文章

  • 11_XML & 反射

    目标 使用反射模拟servlet执行 XML 在servlet中,为了灵活实现不同的路径执行不同的资源,我们需要使...

  • Java基础之反射

    Java基础之反射 反射基本介绍 反射的使用通过反射调用属性和方法通过反射获取配置文件 反射基本介绍 Java反射...

  • 镜面反射矩阵的推导

    镜面反射是以镜面作为反射平面,实物与反射物到反射平面的距离相等,实物与反射物方向相反,所以,反射矩阵由反射平面确定...

  • reflect.go包学习_之二 指针操作提高反射性能 反射应用

    reflect.go包学习_之二 指针操作提高反射性能 反射应用 反射创建实例 反射信息、反射调用方法、反射修改值...

  • Java互联网公司-经典面试题附答案

    基础:Java 反射?反射有什么缺点?你是怎么理解反射的(为什么框架需要反射)?优点:反射具有解耦性,缺点:反射属...

  • Java反射与joor反射库的使用

    java原生反射的使用 反射构造对象 反射方法 反射字段 joor反射库的使用 github:https://gi...

  • Java反射

    什么是反射? 反射的作用? 反射性能优化?

  • 反射三定律

    反射第一定律:反射可以将interface类型变量转换成反射对象 反射第二定律:反射可以将反射对象还原成inter...

  • 反射

    1.反射是什么?反射的定义,概念 2.为什么要学反射? 3.怎么使用反射?反射的使用

  • 一周岁前做好两件事,孩子就不会语言迟缓,保证口齿伶俐

    与语言发展相关的原始反射有四个:张口反射、足跖反射、抓握反射和手拉反射,每个反射的发生、发展和整合都是次第进行的,...

网友评论

    本文标题:11_XML & 反射

    本文链接:https://www.haomeiwen.com/subject/vfnnfxtx.html