注解和XML

注解

注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记,以后javac编译器,开发工具和其他程序可以用反射来了解类及各种元素上的标记情况。Annotation可以标记在包、类、字段、方法、方法的参数以及局部变量等之上。

使用JDK内置Annotation

public class TestAnnotation {
    public static void main(String[] args) {
        /*
            忽略编译器警告,让编辑器去掉黄色警告
            unchecked:忽略泛型类型检查警告
            serial:忽略序列化对象没有实现系列化版本号警告
            deprecation:忽略过时方法/类警告
            all:忽略所有警告
        */
        @SuppressWarnings("unused")
        int a = 9;
    }

    /*
        标记方法过时,简单说就是让编辑器在方法名上加上中划线
    */
    @Deprecated
    public void div() {
    }

    /*
        标记方法是实现父类型或接口中的方法
        简单说:如果父类/接口中没有该方法,编辑器会提示错误
    */
    @Override
    public String toString() {
        return super.toString();
    }
}

使用自定义Annotation

使用自定义Annotation必须有3个步骤,即定义Annotation类型,标注Annotation到目标上,将标注Annotation的类交于第三方程序解析。类比盖章,首先刻章(定义类型),再盖章(标注),最后识别章(解析)。

JUnit4.x使用(频繁)

junit4.x基于Java5开始的版本,支持注解

步骤:

  1. 把junit4.x的测试jar,添加到该项目中来;
  2. 定义一个测试类EmployeeDAOTest,一般的,测试类的名字:XxxTest,Xxx表示一个模块名称
  3. 在EmployeeDAOTest中编写测试方法:如
@Test
public void testXxx() throws Exception{
    //TODO
}
注意:方法是public修饰的,无返回值,该方法上必须贴有@Test标签,xxx表示测试的功能名
  1. 选择某一个测试方法,鼠标右键选择[run as junit],或选中测试类,表示测试该类中所有的测试方法

测试方法执行顺序:

若要在测试方法之前做准备操作:EmployeeDAOTest随意定义一个方法并使用@Before标注;

若要在测试方法之后做回收操作:EmployeeDAOTest随意定义一个方法并使用@After标注:

特点:每次执行测试方法之前都会执行Before方法,每次执行测试方法之后都会执行After方法

有没有方式只初始化一次和最终销毁一次

  • @BeforeClass标签:在所有的Before方法之前执行,只在最初执行一次,只能修饰静态方法;
  • @AfterClass标签:在所有的After方法之后执行,只在最后执行一次,只能修饰静态方法;

执行顺序:BeforeClass --> (Before -> Test -> After 多个测试方法) --> AfterClass

XML语法和解析

XML概述

XML(eXtensible Markup Language),是一种可扩展的标记语言,类似HTML


HTML:显示页面、网页,自带标签
XML:传输数据,而非显示数据
XML标签没有被预定义,需要用户自行定义标签

XML技术是W3C(World Wide Web Consortium万维网联盟)组织发布的,目前遵循的是W3C组织 于2000年发布的XML1.0规范

XML有两个编码,即内容编码和文件本身编码,要保证两个编码相同,都设置为UTF-8

一个XML文档必须有且只有一个根标签,其他标签都是这个根标签的子标签或孙标签。

基本语法

在编写XML文档时,需要先使用文档声明来声明XML文档,且必须出现在文档的第一行。

最简单的语法:<?xml version="1.0"?>

用encoding属性说明文档所使用的字符编码,默认为UTF-8。保存在磁盘上的文件编码要与声明的编码一致。如:

<?xml version="1.0" encoding="UTF-8"?>

用standalone属性说明文档是否独立,即是否依赖其他文档。如:

<?xml version="1.0" standalone="yes"?>

比如通讯录文件(Contacts.xml)记录了多个联系人:

<?xml version="1.0" encoding="UTF-8"?>
<contacts>
    <linkman>
        <name>靓仔</name>
        <tlePhonew>18812345678</tlePhonew>
    </linkman>
    <linkman>
        <name>小兰</name>
        <tlePhonew>19987654321</tlePhonew>
    </linkman>  
</contacts>

XML解析

DOM操作:DOM(Document Object Model):文档对象模型,把文档中的成员描述成一个个对象。(js操作HTML)

特点:在加载的时候,一次性把整个xml文档加载进内存,在内存中形成一棵树(Document对象)。

我们以后使用代码操作Document,其实操作的时内存中的DOM树,和本地磁盘中的XML文件没有直接的关系。

比如:我保存了一个联系人,仅仅是内存中多了一个联系人,但是在XML文件中没有新增的痕迹,除非做同步操作(把内存中的数据更新到XML文件)。

增删改操作完之后,都需要进行同步操作。

缺点:若XML文件过大,可能造成内存溢出

操作XML的增删改查的的时候很简单,但是性能低

使用面向对象的思想把xml中的成员描述成对象:
在XML/html中,一切皆节点(文档节点,元素节点,属性节点,文本节点):

Node:

  • Document:文档对象(XML/HTML文件)
  • Element:元素对象(标签)
  • Attr:属性对象(属于元素)
  • Text:元素之间的内容(Will,空格...)

XML文件:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<contacts>
    <linkman id="1">
        <name>靓仔</name>
        <age>17</age>
    </linkman>
    <linkman id="2">
        <name>淑女</name>
        <age>16</age>
    </linkman>
</contacts>

解析Demo:

package dom;

import java.io.File;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public class DOMParseDemo {
    // 获取被解析的XML的路径
    File file = new File("contacts.xml");

    @Test
    public void testGetDocument() throws Exception {
        // 1.创建DocumentBuilderFactory对象,工厂设计模式往往体现出单利设计模式
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        // 2.通过DocumentBuilderFactory对象来创建DocumentBuilder对象
        DocumentBuilder builder = factory.newDocumentBuilder();
        // 3.通过DocumentBuilder对象创建/解析出一个Document对象
        Document doc = builder.parse(file);
        System.out.println(doc.getClass());// 获取运行类型
        System.out.println(doc);
    }

    // 取出第二个联系人的年龄
    @Test
    public void test1() throws Exception {
        // 1.获取文档对象
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(file);
        // 2.获取根元素contacts
        Element root = doc.getDocumentElement();
        // 3.获取根元素下的第二个linkman元素
        NodeList nodeList = root.getElementsByTagName("linkman");
        Element linkmanEle = (Element) nodeList.item(1);
        // 4.获取第二个linkman元素下的age元素
        Element ageEle = (Element) linkmanEle.getElementsByTagName("age").item(0);
        // 5.获取该name元素的文本内容
        String age = ageEle.getTextContent();
        System.out.println(age);
    }

    // 修改某个元素节点的主体内容:把第二个联系人的年龄改掉
    @Test
    public void test2() throws Exception {
        // 1.获取文档对象
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(file);
        // 2.获取根元素contacts
        Element root = doc.getDocumentElement();
        // 3.获取根元素下的第二个linkman元素
        NodeList nodeList = root.getElementsByTagName("linkman");
        Element linkmanEle = (Element) nodeList.item(1);
        // 4.获取第二个linkman元素下的age元素
        Element ageEle = (Element) linkmanEle.getElementsByTagName("age").item(0);

        // 5.修改年龄
        ageEle.setTextContent("16");

        // 6.进行同步操作,不然文件是不会修改的,因为目前为止操作的只是内存中的“副本”
        TransformerFactory transFactory = TransformerFactory.newInstance();
        Transformer trans = transFactory.newTransformer();
        Source source = new DOMSource(doc);// 别忘了参数doc
        Result target = new StreamResult(file);
        trans.transform(source, target);
    }

    // 向指定元素节点中增加子元素节点:增加一个联系人信息
    @Test
    public void test3() throws Exception {
        Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file);
        Element root = doc.getDocumentElement();

        // 1.创建linkman, name, age元素
        Element linkmanEle = doc.createElement("linkman");
        Element nameEle = doc.createElement("name");
        Element ageEle = doc.createElement("age");

        // 2.给linkman元素设置id属性
        linkmanEle.setAttribute("id", "3");

        // 3.给name, age元素设置文本内容
        nameEle.setTextContent("佳丽");
        ageEle.setTextContent("15");

        // 4.把name, age元素作为linkman元素的子元素
        linkmanEle.appendChild(nameEle);
        linkmanEle.appendChild(ageEle);

        // 5.把linkman元素作为根元素的子元素
        root.appendChild(linkmanEle);

        // 6.同步操作
        TransformerFactory transFactory = TransformerFactory.newInstance();
        Transformer trans = transFactory.newTransformer();
        Source source = new DOMSource(doc);// 别忘了参数doc
        Result target = new StreamResult(file);
        trans.transform(source, target);
    }

    // 删除指定元素节点:删除第三个联系人信息
    @Test
    public void test4() throws Exception {
        // 1.获取文档对象
        Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file);
        // 2.获取根元素contacts
        Element root = doc.getDocumentElement();
        // 3.获取根元素下的第二个linkman元素
        NodeList nodeList = root.getElementsByTagName("linkman");
        Element linkmanEle = (Element) nodeList.item(2);
        // 4.1:root.removeChild(linkmanEle);2:linkmanEle.getParentNode().removeChild(linkmanEle);
        linkmanEle.getParentNode().removeChild(linkmanEle);

        // 5.同步操作
        TransformerFactory transFactory = TransformerFactory.newInstance();
        Transformer trans = transFactory.newTransformer();
        Source source = new DOMSource(doc);// 别忘了参数doc
        Result target = new StreamResult(file);
        trans.transform(source, target);
    }

}

DOM4J解析

DOM4J操作:优点:操作简单,易于理解。缺点:查询操作性能太低

DOM4J是第三方组织编写的优秀的DOM操作工具,使用DOM4J的第一步是引入jar包

优点:更简单,性能更好,在框架大量会用到。

如何学习:

  1. 下载压缩包:dom4j-1.x.x.zip
  2. 开发引入:把dom4j-1.x.x.jar添加到项目的lib目录中,并build path
  3. 怎么使用:阅读dom4j-1.x.x/docs/index --> [Qucik Start] --> guide.html

注意:使用DOM4J,使用到的所有的接口/类全部来源于org.dom4j包。使用DOM4J只能一层一层往下找

xml:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<contacts>
    <linkman id="1">
        <name>靓仔</name>
        <age>17</age>
    </linkman>
    <linkman id="2">
        <name>淑女</name>
        <age>16</age>
    </linkman>
</contacts>

DOM4J Demo

package dom;

import java.io.File;
import java.io.FileWriter;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.junit.Test;

public class DOM4JParseDemo {
    File file = new File("contacts.xml");

    // 新增一个联系人
    @Test
    public void testInset() throws Exception {
        // 1.获取文档对象
        SAXReader reader = new SAXReader();
        Document doc = reader.read(file);

        // 2.获取根元素对象
        Element root = doc.getRootElement();

        // 3.在根元素里创建linkman元素
        Element linkmanEle = root.addElement("linkman");
        linkmanEle.addAttribute("id", "3");

        // 4.在linkman元素中创建name, age子元素
        linkmanEle.addElement("name").setText("杨幂");
        linkmanEle.addElement("age").setText("15");

        // 5.同步操作
        OutputFormat format = OutputFormat.createPrettyPrint();
        XMLWriter writer = new XMLWriter(new FileWriter(file), format);
        writer.write(doc);
        writer.close();
    }

    // 查询联系人信息
    @Test
    public void testQuery() throws Exception {
        // 1.获取文档对象
        SAXReader reader = new SAXReader();
        Document doc = reader.read(file);

        // 2.获取根元素对象
        Element root = doc.getRootElement();

        //3.获取根元素下所有的linkman元素
        List<Element> linkmanEleList = root.elements("linkman");
        for (Element linkmanEle : linkmanEleList) {
            //获取id属性
            String id = linkmanEle.attributeValue("id");
            //获取linkman元素下的name子元素的文本内容
            String name = linkmanEle.element("name").getText();
            //获取linkman元素下的age子元素的文本内容
            String age = linkmanEle.element("age").getText();
            System.out.println(id + "," + name + "," + age);
        }
    }
}

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注