Servlet Day2

Servlet

day2_2023.10.10

XML,注解

掌握内容:

1,元注解的概念用法
2,注解属性值的注入
3,会写xml标签,能看懂xml约束

注解

注解概念:用来说明程序的,是给计算机看的
注释概念:用文字描述程序,给程序员看的,不需要被程序读取

注解定义:

annotation,也称为元数据。是一种代码级别的说明,是jdk1.5之后引入的一个新特性,和类、接口、枚举在同一个层次的
可以声明在包、类、字段、方法、局部变量、方法参数…的前面,用来对这些元素进行说明,注释。
总结:
1,1.5之后的新特性
2,说明程序
3,使用注解 : @注解名称

作用分类:

1,编写文档:通过代码里标识的元数据生成文档,生成一个类的说明文档,类似于API文档
在桌面上新建个文件夹->里面编写一个java文件->保存ANSI格式

public class AnnotationDemo {
        /**
         * 计算两个数的和
         * @param a 整数
         * @param b 整数
         * @return  两个的数的和
         */
        public int add(int a,int b){
            return a+b;
        }
    }

在文件夹位置,打开cmd窗口,输入命令 : javadoc java文件名
可以生成说明的文档
2,代码分析:通过代码里标识的元数据对代码进行分析(使用反射)
3,编译检查:通过代码里标识的元数据,让编译器能够实现基本的编译,比如@Override 注解,可以检查方法的重写是否正确

JDK中预定义的一些注解

1,@Override :检测被该注解标注的方法,是否继承自 父类(接口)
2,@Deprecated:标注该内容已经过时了
3,@SuppressWarnings(“all”) 压制警告,一般传递参数all

自定义注解

看了注解的原码,分为两个部分

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

注解格式:
上面部分: 元注解
下面部分:注解名称,注解声明

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

@Target(ElementType.FIELD)
public @interface MyAnnotation {
}

在这里插入图片描述
通过对注解的原码的反编译,得出,注解本质其实就是一个接口
接口中只能定义抽象方法,所以注解中也只能定义对应的内容
注解中可以定义的属性 :接口中定义的抽象方法,我们在注解中,称为注解的属性
要求:
1,属性的返回值类型
基本数据类型
String类型
枚举
注解
以上类型的数组

public @interface MyAnnotation {
    //注解的属性
    String show(); // 接口中称为show()方法,注解中称为show 属性
    //void show1(); // 注解中不能定义返回值为空的属性
    int show1();

    Person person(); //定义枚举类型返回值

    MyAnnotation2 annotation2();

    String[] strs(); //返回值是字符串数组
}

注解的使用

枚举类
public enum  Person {
    P1,P2
}



注解
public @interface MyAnnotation {
    //注解的属性
   // int age();
   // String name();
   // //如果属性加了default,使用的时候可以不指定值
   // String gender() default "男";
    //int value();
    //Person person();
    String[] strs();
}

测试类
//@MyAnnotation(age = 20)
//@MyAnnotation(age = 20,name="张三",value = 100)
//@MyAnnotation(value = 100) //注解中只有一个value属性可以这么写
//@MyAnnotation(value = 100,person = Person.P1)
@MyAnnotation(strs = {"a","b"})
public class Student {

}

注解使用的特点:
1,在注解中定义了属性,使用注解的时候,需要给对应的属性赋值,定义什么类型,赋值什么类型
2,如果定义属性的时候,使用了default关键字给属性默认初始值了,可以不进行赋值,自动取默认值
3,如果只有一个属性需要赋值,且属性名是value,那么value可以省略
4,数组赋值的时候,需要使用{}包裹起来,如果数组只有一个值,{}可以省略

元注解:用来描述注解的注解

如:
@Target() 描述注解可以用在哪些位置
属性是:ElementType[] value();
使用的时候,需要取ElementType的值,ElementType包含的值表示一些位置
TYPE:如果取值为type,表示这个注解只能用在类上
FIELD:表示注解注解用在成员属性上
METHOD:表示注解用在成员方法上
CONSTRUCTOR:表示注解用在构造方法上
@Retention() 描述注解被保留的阶段
属性:RetentionPolicy value();
取值范围是 :RetentionPolicy的值,三个值,分别表示阶段
SOURCE: 原码阶段
CLASS:字节码阶段
RUNTIME:运行阶段
@Documented() :描述注解是否被抽取到api文档中
@Inherited() :描述注解是否被子类继承

注解使用

使用注解,获取全类名、方法名,结合反射,调用不同类的不同方法

package com.iweb.tongda64.test1;

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

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String className();
    String methodName();
}

/*
Person类
 */
public class Person {
    public void eat(){
        System.out.println("eat....");
    }
}


public class Student {
    public void study(){
        System.out.println("study....");
    }
}


@MyAnnotation(className = "com.iweb.tongda64.test1.Person",methodName = "eat")
public class ReflectDemo {
    public static void main(String[] args) throws Exception {
       
        //1,先获取类对象
        Class<ReflectDemo> demo = ReflectDemo.class;
        //通过类对象,可以获取到注解
        MyAnnotation annotation = demo.getAnnotation(MyAnnotation.class);

        //2,获取配置文件中的数据
        String className = annotation.className();
        String methodName = annotation.methodName();
        //3,获取Class类对象
        Class cls = Class.forName(className);
        //4,创建对象
        Object obj = cls.newInstance();
        //5,通过Class类对象获取到方法
        Method method = cls.getMethod(methodName);
        //6,执行方法
        method.invoke(obj);
    }
}
XML

1,概念: Extensible Markup Language 可扩展标记语言
可扩展:标签是自定义的。 比如 HTML是预先定义的
2,功能:
存储数据
1,配置文件使用
常用的配置文件:
properties 文件:
name=xxx
age=xxx
xml文件 :
< user >
< name >xxxx< /name >
< age >xxx< /age >
< /user >
2,在网络中传输
3,xml与html的区别
1,xml标签都是自定义的,html标签是预定义的
2,xml语法严格,html语法松散,xml想写对很难,html想写错很难
3,xml是存储数据的,html是展示数据的
4,语法
基本语法:
1,xml文档的后缀名是 .xml
2,xml第一行必须定义为文档声明
3,xml文档中有且仅有一个根标签
4,属性值必须使用引号(单双都可)引起来
5,标签必须正确关闭,双标签,可以定义自闭和标签
6,xml标签名称区分大小写
写一个users.xml


<?xml version='1.0' ?>

<users>
	<user id='1'>
		<name>zhangsan</name>
		<age>20</age>
		<gender>nan</gender>
	</user>
	
	<user id='2'>
		<name>lisi</name>
		<age>22</age>
		<gender>nv</gender>
	</user>
</users>

组成部分
1,文档声明
格式:< ?xml version=‘1.0’ ? >
属性列表:
version:版本号,必须的属性
encoding:编码方式,告知解析引擎当前文档使用的字符集,默认值:ISO-8859-1(格式要和文件格式相符才能解析中文,idea中是可以实现自动更改)
standalone:是否独立
取值:
yes:不依赖其他文件
no:依赖于其他文件
2,指令(了解):结合css的

<?xml-stylesheet type="text/css" href="a.css" ?>

3,标签:标签名称是自定义的
规则 :
名称可以包含字母、数字以及其他的字符
名称不能以数字或者标点符号开始
名称不能以字母 xml(或者 XML、Xml 等等)开始
名称不能包含空格
4,属性:
id属性值唯一
5,文本
< code >
if(a>b && a<c){} 这样直接写会报错
if(a>b && a<c){}
< /code >
cdata区:在该区域中的数据会被原样展示
< ![CDATA[
if(a>b && a<c){}
]] >

约束:规定xml文档的书写规则

作为框架的使用者:
1,能够在xml中引入约束文档
2,能够简单的读懂约束文档
分类:
dtd,schema
1,DTD:一种简单的约束技术
外部文件约束
student.dtd

<!ELEMENT students (student*)>
<!ELEMENT student (name,age,sex)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT sex (#PCDATA)>
<!ATTLIST student number ID #REQUIRED>

student.xml


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE students SYSTEM "student.dtd">

<students>
    <student number="s001">
        <name>zhangsan</name>
        <age>23</age>
        <sex>nan</sex>
    </student>
    <student number="s002">
        <name>zhangsan</name>
        <age>23</age>
        <sex>nan</sex>
    </student>
</students>

2,将约束定义在内部

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE students [
<!ELEMENT students (student*)>
<!ELEMENT student (name,age,sex)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT sex (#PCDATA)>
<!ATTLIST student number ID #REQUIRED>
    
]>

<students>
    <student number="s001">
        <name>zhangsan</name>
        <age>23</age>
        <sex>nan</sex>
    </student>
    <student number="s002">
        <name>zhangsan</name>
        <age>23</age>
        <sex>nan</sex>
    </student>
</students>

2,schema:一种复杂的约束技术
student.xsd


<?xml version="1.0"?>
<!--xmlns:xsd="http://www.w3.org/2001/XMLSchema" 表示数据类型等定义来自w3-->
<!-- targetNamespace 表示文档中要定义的元素来自什么命名空间-->
<!-- xmlns="http://www.w3schools.com"表示此文档的默认命名空间是什么-->
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3schools.com"
xmlns="http://www.w3schools.com"
elementFormDefault="qualified"><!--表示要求xml文档的每一个元素都要有命名空间指定-->
<!--定义主体部分-->
<!-- 定义一个元素,名称是students,类型是自定义的studnetsType类型,所以下面要把studentType类型定义-->
<xsd:element name="students" type="studentsType"/>
<!-- 自定义类型studentType,和上面对应-->
<xsd:complexType name="studentsType">
<!-- sequence表示按顺序出现student元素,类型为自定义类型studentType,最少0最多不限次数-->
<xsd:sequence>
<xsd:element name="student" type="studentType" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<!--定义自定义复杂类型studentType-->
<xsd:complexType name="studentType">
<!--依次出现-->
<xsd:sequence>
<!--name元素 类型是string-->
<xsd:element name="name" type="xsd:string"/>
<!-- age元素,类型是自定义ageType类型-->
<xsd:element name="age" type="ageType"/>
<!-- sex元素,类型是自定义的sexType类型-->
<xsd:element name="sex" type="sexType"/>
</xsd:sequence>
<!-- number属性,类型是自定义numberType类型-->
<xsd:attribute name="number" type="numberType" use="required"/>
</xsd:complexType>
<!--简单类型ageType-->
<xsd:simpleType name="ageType">
<!--基本格式是integer-->
<xsd:restriction base="xsd:integer">
<!--最小值-->
<xsd:minInclusive value="0"/>
<!--最大值-->
<xsd:maxInclusive value="256"/>
</xsd:restriction>
</xsd:simpleType>
<!-- 自定义简单类型sexType-->
<xsd:simpleType name="sexType">
<!--基本格式是string-->
<xsd:restriction base="xsd:string">
<!--选值1-->
<xsd:enumeration value="man"/>
<!--选值2-->
<xsd:enumeration value="women"/>
</xsd:restriction>
</xsd:simpleType>
<!-- 自定义简单类型sexType-->
<xsd:simpleType name="numberType">
<!--基本格式是string-->
<xsd:restriction base="xsd:string">
<!--选值1-->
<xsd:pattern value="airui_\d{4}"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>

student.xml

<?xml version="1.0" encoding="UTF-8"?>
<!--
 1,填写xml文档的根元素
 2,引入 xsi前缀,固定格式,w3c提供的约束文档 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3,引入xsd文件命名空间 xsi:schemaLocation="http://www.w3schools.com student.xsd"
 schemaLocation,表示文档路径,student.xsd称为命名空间 如果要使用,每次都需要加上文档路径
 4,为每一个xsd约束声明一个前缀,作为表示 xmlns:a="http://www.w3schools.com" 表示前缀简写为a
不写的话,表示忽略
 如果被多个文档共同约束,有多个不同的命名空间
 xsi:schemaLocation="http://www.w3schools.com1 student1.xsd"
 xsi:schemaLocation="http://www.w3schools.com2 student2.xsd"
就需要写多个前缀
 xmlns:a="http://www.w3schools.com"
 xmlns:b="http://www.w3schools.com"
-->
<students xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3schools.com student.xsd"
xmlns="http://www.w3schools.com"
>
<student number="airui_1234">
<name>zhangsan</name>
<age>11</age>
<sex>man</sex>
</student>
</students>
解析:操作xml文档,将文档中的数据读取到内存中

操作xml文档
1,解析: 将文档中的数据读取到内存中
2,写入:将内存中的数据保存到xml文档中,持久化存储
解析xml的方式
1,DOM:将标记语言文档一次性加载进内存,在内存中形成一颗dom树
有点:操作方便,可以对文档进行CRUD操作
缺点:比较消耗内存,文档1M可能有1000-10000倍
2,SAX:逐行读取,基于事件驱动是。
优点:不占内存,比如手机用的较多
缺点:只能读取,不能增删改
服务器端一般只用DOM方式,安卓等客户端使用的SAX
JAVAEE主要是做服务器端开发,所以了解DOM思想

XML常见的解析器

1,JAXP:sun公司提供的解析器,支持dom和sax两种思想,性能不好,用的少
2,DOM4J:一款非常优秀的解析器,基于DOM思想解析的
dom4j是一个Java的XML API,是jdom的升级品,用来读写XML文件的。dom4j是一个十分优秀的JavaXML API,具有性能优异、功能强大和极其易使用的特点,它的性能超过sun公司官方的dom技术,同时它也是一个开放源代码的软件,可以在SourceForge上找到它。在IBM developerWorks上面还可以找到一篇文章,对主流的Java XML API进行的性能、功能和易用性的评测,所以可以知道dom4j无论在哪个方面都是非常出色的。如今可以看到越来越多的Java软件都在使用dom4j来读写XML,特别值得一提的是连Sun的JAXM也在用dom4j。这已经是必须使用的jar包, Hibernate也用它来读写配置文件。
3,Jsoup:jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。
4,PULL:Android操作系统内置的解析器,sax方式的

/*
读取xml文档信息
 */
public class XMLDemo01 {
    public static void main(String[] args) throws DocumentException {
        //创建Reader对象
        SAXReader saxReader = new SAXReader();
        //通过对象去读取文件
        Document document = saxReader.read(new File("src/xml/student.xml"));
        //通过document对象获取元素
        Element rootElement = document.getRootElement();
        System.out.println(rootElement);
        //通过根节点去获取其他的子元素,返回节点的迭代器
        Iterator iterator = rootElement.elementIterator();
        //遍历
        while (iterator.hasNext()){
            Element element = (Element) iterator.next();
            //获取节点的名称
            System.out.println(element.getName());
            //获取节点的属性
            Attribute attribute = element.attribute("number");

            //获取student节点的子节点
            Element name = element.element("name");
            Element age = element.element("age");
            Element sex = element.element("sex");
            System.out.println(name.getText());
            System.out.println(age.getText());
            System.out.println(sex.getText());
        }
    }
}

写一个xml文档内容

/*
写一个xml文档信息
 */
public class XMLDemo02 {
    public static void main(String[] args) throws Exception {
        writeXML(new File("src/xml/student1.xml"));
    }

    //封装一个方法
    public static void writeXML(File file) throws Exception {
        //创建document对象
        Document document = DocumentHelper.createDocument();
        //通过document对象,添加根节点
        Element root = document.addElement("students");

        //通过跟节点,添加子节点
        Element student = root.addElement("student");
        //student节点再继续加属性、子节点
        Element number = student.addAttribute("number", "tongda_1234");

        //加name子节点
        Element name = student.addElement("name");
        Element age = student.addElement("age");

        //给name、age节点加点内容
        name.addText("张三");
        age.addText("20");

        //指定文档的写入格式
        OutputFormat format = OutputFormat.createPrettyPrint();
        //写入xml文件

        XMLWriter writer = new XMLWriter(new FileOutputStream(file), format);
        //将document节点传入writer对象
        writer.write(document);
        System.out.println("xml写入完成!");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值