关于java:JavaSE第25篇枚举XML

51次阅读

共计 12674 个字符,预计需要花费 32 分钟才能阅读完成。

外围概述:在当前的我的项目开发中,在我的项目中和业务状态相干的标识咱们个别应用枚举来治理,并且在开发中咱们会应用框架 + 配置文件进步程序的开发效率和灵活性,其中咱们应用 xml 用作配置文件,本篇咱们将枚举、XML

第一章:枚举

外围概述:在当前的我的项目开发中,在我的项目中和业务状态相干的标识咱们个别应用枚举来治理,并且在开发中咱们会应用框架 + 配置文件进步程序的开发效率和灵活性,其中咱们应用 xml 用作配置文件,本篇咱们将枚举、XML

1.1- 概述(理解)

枚举是 JDK1.5 新增的援用数据类型,和类,接口是一个级别的,定义枚举的关键字为enum

java.lang.Enum类,是所有枚举的父类。

枚举的实质就是一个类的多个对象。

1.2- 枚举的定义和应用(重要)

定义

格局:public enmu 枚举名{}

  • 枚举中的常量名字大写,多个常量之间逗号离开,最初一个常量能够写分号,也能够不写。每一个常量,都示意这个类的对象。修饰符为public static final
  • 枚举中有默认的无参数的 private 润饰的构造方法,如果手写构造方法,也必须是公有润饰的。而且构造方法必须写在常量的前面,这时最初一个常量就必须要写分号。

示例

示例 1:(罕用)

public enum  Color {
    // 枚举的动态常量
    RED,GREEN,YELLOW
}

示例 2:(理解)

public enum Color{
    // 枚举动态常量,间接为变量 color 赋值
    RED("红色"),GREEN("绿色"),YELLOW("黄色");
    private String color;
    private Color(String color){this.color = color ;}
    // 省略 get/set
}

应用枚举

因为枚举的常量为动态润饰能够间接 枚举名. 调用

public static void main(String[] args){
    Color color = Color.GREEN;
    System.out.println(color);
    System.out.println(color.getName());
}

第二章:XML

2.1- 概述(理解)

什么是 XML

XML:可扩大标记语言(EXtensible Markup Language

XML 它是一种 标记语言,很相似 HTML,HTML 文件也是 XML 文档,标签都是自定义的。如:<user></user> 或 <student></student>

W3C 在 1998 年 2 月公布 1.0 版本,2004 年 2 月又公布 1.1 版本,单因为 1.1 版本不能向下兼容 1.0 版本,所以 1.1 没有人用。同时,在 2004 年 2 月 W3C 又公布了 1.0 版本的第三版。咱们要学习的还是 1.0 版本

XML 与 HTML 的差别

  • xml 标签都是自定义的,html 标签是预约义。
  • xml 的语法严格,html 语法涣散。
  • xml 是存储数据的,html 是展现数据。

XML 的作用

XML 是存储数据的。示例如下:

<?xml version="1.0" encoding="UTF-8"?>
<persons>
    <person id="p001">
        <name> 张三 </name>
    </person>
    <person id="p002">
        <name> 李四 </name>
    </person>
</persons>

相似于 Java 代码,示例如下:

class Person{
    String id;
    String name;
}

public void test(){HashSet<Person> persons = new HashSet<Person>();
    persons.add(new Person("p001","张三") );
    persons.add(new Person("p002","李四") );
}

XML 可作用配置文件。示例如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean className="com.it.bean.User">
        <property name="username" value="jack"></property>
    </bean>
</beans>

相似于 Java 代码,示例如下:

class User{
    private String username;
    private String pws;
    // 补全 set\get 办法
}
class Test{public static void main(String[] args){Class clazz = Class.forName("com.it.bean.User");
        Object obj = clazz.newInstance();
        Method method = clazz.getMethod("setUsername",String.class);
        method.invoke(obj,"jack");
    }
}

2.2-XML 的组成(重点)

组成部分:文档申明

XML 文档申明格局:

<?xml version="1.0" encoding="UTF-8"?>
  1. versioin:指定 XML 文档版本。必须属性,因为咱们不会抉择 1.1,只会抉择 1.0;
  2. encoding:指定以后文档的编码。可选属性,默认值是 utf-8;

注意事项:

  1. 文档申明必须为 <?xml 结尾,以?> 完结;
  2. 文档申明必须从文档的 0 行 0 列地位开始;
  3. 文档申明只有 2 个属性:

组成部分:元素

元素 element

<bean></bean>

注意事项:

  1. 元素是 XML 文档中最重要的组成部分,
  2. 一般元素的构造开始标签、元素体、完结标签组成。例如:<hello> 大家好 </hello>
  3. 元素体:元素体能够是元素,也能够是文本,例如:<b><a> 你好 </a></b>
  4. 空元素:空元素只有开始标签,而没有完结标签,但元素必须本人闭合,例如:<c/>
  5. 元素命名:

    • 辨别大小写
    • 不能应用空格,不能应用冒号:
    • 不倡议以 XML、xml、Xml 结尾

格式化良好的 XML 文档,必须只有一个根元素。

组成部分:属性

属性 attribute

<bean id=""className="">

注意事项:

  1. 属性是元素的一部分,它必须呈现在元素的开始标签中
  2. 属性的定义格局:属性名 = 属性值,其中属性值必须应用单引或双引
  3. 一个元素能够有 0~N 个属性,但一个元素中不能呈现同名属性
  4. 属性名不能应用空格、冒号等特殊字符,且必须以字母结尾

组成部分:正文

XML 的正文,以 “<!--”开始,以“-->” 完结。正文内容会被 XML 解析器疏忽!

组成部分:转义字符

因为很多符号曾经被 XML 文档构造所应用,所以在元素体或属性值中想应用这些符号就必须应用转义字符,例如:<”、“>”、“”、“”、“&

2.3-XML 束缚(理解)

2.3.1- 什么是 XML 束缚

在 XML 技术里,能够编写一个文档来束缚一个 XML 文档的书写标准,这称之为 XML 束缚。
常见的 xml 束缚:DTD、Schema

2.3.2-DTD 束缚

什么是 DTD

DTD(Document Type Definition),文档类型定义,用来束缚 XML 文档。规定 XML 文档中元素的名称,子元素的名称及程序,元素的属性等。

重点要求

开发中,咱们很少本人编写 DTD 束缚文档,通常状况咱们都是通过框架提供的 DTD 束缚文档,编写对应的 XML 文档。常见框架应用 DTD 束缚有:SpringMVC、MyBatis 等。

通过提供的 DTD“bean.dtd”编写 XML。bean.dtd束缚如下:

<?xml version="1.0" encoding="UTF-8"?>
<!--
    DTD 文档。模仿 spring 标准,如果开发人员须要在 xml 应用以后 DTD 束缚,必须包含 DOCTYPE。格局如下:<!DOCTYPE beans SYSTEM "bean.dtd">
-->
<!-- 束缚 xml 中必须有一个根元素 beans,beans 元素外部能够嵌套 bean 元素和 import 元素,* 示意可有可无 -->
<!ELEMENT beans (bean*,import*) >
<!--bean 元素中可有 propert 元素 -->
<!ELEMENT bean (property*)>
<!--propert 元素外部能够设置文本 -->
<!ELEMENT property (#PCDATA)>
<!--import 元素外部能够设置文本 -->
<!ELEMENT import (#PCDATA)>
<!--bean 元素必须有 id 和 calssName 属性,且属性值是文本 -->
<!ATTLIST bean id CDATA #REQUIRED
               className CDATA #REQUIRED
>
<!--property 元素必须有 name 和 value 属性,且属性值是文本 -->
<!ATTLIST property name CDATA #REQUIRED
                   value CDATA #REQUIRED
>
<!--import 必须以文本形式导入 -->
<!ATTLIST import resource CDATA #REQUIRED>

案例实现

自定义 xml 实现合乎上述 bean.dtd 束缚

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans SYSTEM "bean.dtd">
<beans>
    <bean id=""className=""></bean>
    
    <bean id=""className="">
        <property name=""value=""></property>
        <property name=""value=""></property>
    </bean>
    
    <import resource=""></import>
    <import resource=""></import>

</beans>

2.3.3- Schema 束缚

什么是 Schema

  • Schema 是新的 XML 文档束缚;
  • Schema 要比 DTD 弱小很多,是 DTD 替代者;
  • Schema 自身也是 XML 文档,但 Schema 文档的扩大名为 xsd,而不是 xml;
  • Schema 性能更弱小,数据类型更欠缺;
  • Schema 反对名称空间;

重点要求

与 DTD 一样,要求能够通过 schema 束缚文档编写 xml 文档。常见框架应用 schema 的有:Spring 等

通过提供“bean-schema.xsd”编写 xml 文档。

<?xml version="1.0" encoding="UTF-8"?>
<!-- 
    Schema 实例文档。模仿 spring 标准,如果开发人员须要在 xml 应用以后 Schema 束缚,必须包含指定命名空间。格局如下:<beans xmlns="http://www.penglei666.com/bean"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.penglei666.com/bean bean-schema.xsd"
    >
-->
<schema xmlns="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://www.penglei666.com/bean"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xmlns:tns="http://www.penglei666.com/bean"
        elementFormDefault="qualified">
    <!-- 申明根标签 -->
    <element name="beans">
        <complexType>
            <choice minOccurs="0" maxOccurs="unbounded">
                <element name="bean">
                    <complexType>
                        <sequence minOccurs="0" maxOccurs="unbounded">
                            <element name="property">
                                <complexType>
                                    <attribute name="name" use="required"></attribute>
                                    <attribute name="value" use="required"></attribute>
                                </complexType>
                            </element>
                        </sequence>
                        <attribute name="id" use="required"></attribute>
                        <attribute name="className" use="required"></attribute>
                    </complexType>
                </element>
                <element name="import">
                    <complexType>
                        <attribute name="resource" use="required"></attribute>
                    </complexType>
                </element>
            </choice>
        </complexType>
    </element>
</schema>

案例实现

自定义 xml 合乎 Schema 束缚

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.penglei666.com/bean"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.penglei666.com/bean bean-schema.xsd"
>
    <bean id=""className=""></bean>
    <bean id=""className="">
        <property name=""value=""/>
        <property name=""value=""/>
    </bean>
    
    <import resource=""/>
    <import resource=""/>
</beans>

2.3.4- 命名空间

什么是命名空间

如果一个 XML 文档中应用多个 Schema 文件,而这些 Schema 文件中定义了雷同名称的元素时就会呈现名字抵触。这就像一个 Java 文件中应用了 import java.util. 和 import java.sql. 时,在应用 Date 类时,那么就不明确 Date 是哪个包下的 Date 了。

总之名称空间就是用来解决元素和属性的名称抵触问题,与 Java 中的包是同一用处。如果每个元素和属性都有本人的名称空间,那么就不会呈现名字抵触问题,就像是每个类都有本人所在的包一样,那么类名就不会呈现抵触。

束缚文档和 xml 关系

当 W3C 提出 Schema 束缚标准时,就提供“官网束缚文档”。咱们通过官网文档,必须“自定义 schema 束缚文档”,开发中“自定义文档”由框架编写者提供。咱们提供“自定义文档”限定,编写出本人的 xml 文档。

申明命名空间

默认命名空间:<xxx xmlns=””>,应用 < 标签 >
显式命名空间:<xxx xmlns: 别名 =””>,应用 < 别名: 标签 >

2.4-XML 解析(重点)

2.4.1- 什么是 XML 解析

当将数据存储在 XML 后,咱们就心愿通过程序取得 XML 的内容。如果咱们应用 Java 根底所学习的 IO 常识是能够实现的,不过你须要十分繁琐的操作才能够实现,且开发中会遇到不同问题(只读、读写)。人们为不同问题提供不同的解析形式,并提交对应的解析器,不便开发人员操作 XML。

2.4.2- 常见的解析形式和解析器

开发中比拟常见的解析形式有三种,如下:

DOM:要求解析器把整个 XML 文档装载到内存,并解析成一个 Document 对象。

长处:元素与元素之间保留构造关系,故能够进行增删改查操作。
毛病:XML 文档过大,可能呈现内存溢出浮现。

SAX:是一种速度更快,更无效的办法。它逐行扫描文档,一边扫描一边解析。并以事件驱动的形式进行具体解析,每执行一行,都将触发对应的事件。(理解)

长处:处理速度快,能够解决大文件
毛病:只能读,逐行后将开释资源。

PULL:Android 内置的 XML 解析形式

相似 SAX。(理解)

解析器:就是依据不同的解析形式提供的具体实现。有的解析器操作过于繁琐,为了不便开发人员,有提供易于操作的解析开发包。

2.4.3-dom 解析原理和构造模型

XML DOM 将整个 XML 文档加载到内存,生成一个 DOM 树,并取得一个 Document 对象,通过 Document 对象就能够对 DOM 进行操作。

DOM 中的外围概念就是节点,在 XML 文档中的元素、属性、文本等,在 DOM 中都是节点!

2.4.4-API 应用

DOM4J 是一个 Java 的 XML API,具备性能优异、功能强大和极其易使用的特点,它的性能超过 sun 公司官网的 dom 技术,现在能够看到越来越多的 Java 软件都在应用 DOM4J 来读写 XML。

如果想要应用 DOM4J,须要引入反对 xpath 的 jar 包 dom4j-1.6.1.jar

jar 包下载链接:https://pan.baidu.com/s/1nW0g…
提取码:wt60

DOM4J 必须应用外围类 SaxReader 加载 xml 文档取得 Document,通过 Document 对象取得文档的根元素,而后就能够操作了。

SaxReader 对象

read(…) 加载执行 xml 文档

Document 对象

getRootElement() 取得根元素

Element 对象

elements(…) 取得指定名称的所有子元素。能够不指定名称
element(…) 取得指定名称第一个子元素。能够不指定名称
getName() 取得以后元素的元素名
attributeValue(…) 取得指定属性名的属性值
elementText(…) 取得指定名称子元素的文本值
getText() 取得以后元素的文本内容

案例

编写 xml,beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean id="001" className="cn.it.demo.User">
        <property name="user" value="jacl"></property>
        <property name="user" value="rose"></property>
    </bean>

    <bean id="002" className="cn.it.demo.Admin">
        <property name="user" value="admin"></property>
        <property name="user" value="write"></property>
    </bean>
</beans>

java 代码解析 XML

public static void main(String[] args) throws Exception {SAXReader sax = new SAXReader();
    Document document = sax.read("beans.xml");

    Element elemRoot = document.getRootElement();
    List<Element>list = elemRoot.elements();
  
    for(Element element : list){String id =element.attributeValue("id");
        String className = element.attributeValue("className");
        System.out.println(id+""+className);

        List<Element>listElem = element.elements();
        for(Element elem : listElem){String name = elem.attributeValue("name");
            String value = elem.attributeValue("value");
            System.out.println(name+""+value);
        }
    }

2.5-Xpath 解析 XML(重点)

概述

  • XPath 是一门在 XML、html 文档中查找信息的语言。
  • XPath 是一个 W3C 规范,可通过 W3CSchool 文档查阅语法

因为 DOM4J 在解析 XML 时只能一层一层解析,所以当 XML 文件层数过多时应用会很不不便,联合 XPATH 就能够间接获取到某个元素

应用 dom4j 反对 xpath 具体操作

默认的状况下,dom4j 不反对 xpath,如果想要在 dom4j 外面应用 xpath,须要引入反对 xpath 的 jar 包 jaxen-1.1.6.jar

在 dom4j 外面提供了两个办法,用来反对 xpath,扩大的 API 如下

List<Node> selectNodes("xpath 表达式"),用来获取多个节点
Node selectSingleNode("xpath 表达式"),用来获取一个节点

xpath 表达式罕用查问模式

第一种:

/AAA/DDD/BBB:示意一层一层的,AAA 上面 DDD 上面的 BBB

第二种:

//BBB:示意和这个名称雷同,示意只有名称是 BBB 都失去

第三种:

/*: 所有元素

第四种:

BBB[1]:示意第一个 BBB 元素
BBB[last()]:示意最初一个 BBB 元素

第五种:

//BBB[@id]:示意只有 BBB 元素下面有 id 属性 都失去

第六种:

//BBB[@id='b1'] 示意元素名称是 BBB, 在 BBB 下面有 id 属性,并且 id 的属性值是 b1

案例

编写 xml,student.xml

<?xml version="1.0" encoding="UTF-8" ?>
<students>
    <student number="stu_0001">
        <name id="it">
            <xing> 张 </xing>
            <ming> 三 </ming>
        </name>
        <age>18</age>
        <sex>male</sex>
    </student>
    <student number="stu_0002">
        <name>jack</name>
        <age>18</age>
        <sex>female</sex>
    </student>
</students>

Xpath 解析

public static void main(String[] args) throws Exception {SAXReader saxReader=new SAXReader();
        String path = Demo4jXpath.class.getClassLoader().getResource("student.xml").getFile();
        File file = new File(path);
        Document document=saxReader.read(file);

        //4. 联合 xpath 语法查问
        //4.1 查问所有 student 标签
        List<Node> nodes = document.selectNodes("//student");
        for (Node node : nodes) {System.out.println(node);
        }

        System.out.println("--------------------");

        //4.2 查问所有 student 标签下的 name 标签
       nodes = document.selectNodes("//student/name");
        for (Node node : nodes) {System.out.println(node);
        }

        System.out.println("--------------------");

        //4.3 查问 student 标签下带有 id 属性的 name 标签
        nodes = document.selectNodes("//student/name[@id]");
        for (Node node : nodes) {System.out.println(node);
        }
        System.out.println("--------------------");
        //4.4 查问 student 标签下带有 id 属性的 name 标签 并且 id 属性值为 itcast

        nodes = document.selectNodes("//student/name[@id='itcast']");
        for (Node node : nodes) {System.out.println(node);
        }
    }

第三章:综合案例

3.1-B/ S 服务改良

网络编程中的 BS 服务器案例中存在一个问题,咱们在程序中将端口号写死,如果要更换端口号只能批改源代码。这样程序的维护性十分的差。

解决办法:将端口号写在配置文件(xml)中进行读取,须要更换端口号能够间接批改配置文件。

在 src 目录下创立文件 server.xml:

<?xml version="1.0" encoding="utf-8"?>
<server>
    <port>8000</port>
</server>

读取 xml 中的端口号:

public static void main(String[] args)throws Exception{SAXReader saxReader = new SAXReader();
    // 获取类的加载器
    ClassLoader classLoader = TCPServer.class.getClassLoader();
    // 类加载器中获取输出流
    InputStream inputStream = classLoader.getResourceAsStream("server.xml");
    Document document = saxReader.read(inputStream);
    Element rootElement = document.getRootElement();
    //xpath 表达式,获取标签 port
    Node node = rootElement.selectSingleNode("//port");
    // 节点对象强转标签对象
    Element portElement = (Element)node;
    // 获取端口号,转成 int 类型
    int port = Integer.parseInt(portElement.getText());
    ServerSocket server = new ServerSocket(port);
    while(true){Socket socket = server.accept();
        // 开启线程
    }
}

3.2-DI 操作

DI 依赖注入,前面框架篇幅解释。

反射 + XML 解析

需要:

读取 xml 文件,创立 Person 对象并为属性赋值

person.xml 文件如下:

<?xml version="1.0" encoding="UTF-8" ?>
<persons>
    <person className="com.it.domain.Person">
        <property name="name"> 李四 </property>
        <property name="sex"> 男 </property>
    </person>
</persons>

Person 类

package com.it.domain;

import lombok.Data;

@Data
public class Person {
    private String name;
    private String sex;
}

实现

package com.itheima.di;

import com.it.domain.Person;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.List;

/**
 *  <person className="com.it.domain.Person">
         <property name="name"> 张三 </property>
         <property name="address"> 北京市 </property>
    </person>

   要求: DOM4j, 读取 xml 文件
   className 的属性值 com.itheima.domain.Person 反射创立该类的对象
   读取到 name="name"  张三  反射调用 setName()办法存储张三
   读取到 name="address" 反射调用 setAddress()存储北京市

 Person person = new Person();
 person.setName("张三");
 person.setAddress("北京市");
 System.out.println(person);
 */
public class DiDemo {public static void main(String[] args) throws Exception{InputStream inputStream = DiDemo.class.getClassLoader().getResourceAsStream("person.xml");
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read(inputStream);
        // 获取根标签
        Element rootElement = document.getRootElement();
        // 获取子标签 person
        List<Element> personElements = rootElement.elements();
        if(personElements != null && personElements.size() > 0){for(Element personElement : personElements){
               //personElement person 标签对象
                // 获取 person 标签的属性 className 的值
                String className = personElement.attributeValue("className");
                // 反射, 将类退出内存
                Class c = Class.forName(className);
                // 创立类对象
                Object object = c.newInstance();
                // 获取 person 标签的子标签 property
                List<Element> propertyElements = personElement.elements();
                if(propertyElements != null && propertyElements.size() > 0) {for(Element propertyElement : propertyElements){
                        //propertyElement 每个子标签 property
                        // 取出 property 标签的属性 name 和他的标签体文本
                        String name = propertyElement.attributeValue("name");//name
                        String text = propertyElement.getText();// 张三
                        // 反射获取该成员变量的 set 办法, 进行赋值
                        //name setName    address=setAddress
                        String methodName = "set"+name.substring(0,1).toUpperCase()+name.substring(1);
                        Method method = c.getMethod(methodName,String.class);
                        method.invoke(object,text);
                    }
                }
                System.out.println(object);
            }
        }
    }
}

正文完
 0