XML
-
XML 指可扩展标记语言(EXtensible Markup Language),由各种标记(元素==标签)组成。
-
可扩展:所有的标签都是自定义的,可以随意扩展的,如 。
-
XML 是一种标记语言,很类似 HTML,HTML文件也是XML文档。
-
XML 的设计宗旨是传输数据,而非显示数据。
-
XML作用:数据交换、数据存储和作为配置文件。
-
XML 标签没有被预定义。您需要自行定义标签,标签区分大小写。
-
XML 文件后缀为。xml。
-
格式
-
<?xml version="1.0" encoding="UTF-8"?> <person id="110"> <age>18</age> <!--年龄--> <name>张三</name> <!--姓名--> <sex/> <!--性别--> </person>
-
必须要有文件抬头
-
只能有一个根标签。
-
XML 与 HTML 的主要差异
- XML 不是 HTML 的替代。
- XML 和 HTML 为不同的目的而设计。
- XML 被设计为传输和存储数据,其焦点是数据的内容。
- HTML 被设计用来显示数据,其焦点是数据的外观。
- HTML 旨在显示信息,而 XML 旨在传输信息。
XML由七种组成元素构成
-
声明(抬头)
-
元素(标签)
- 区分大小写
- 不能有空格、冒号
- 有且只能有一个根元素
- 声明中常用的属性 version encoding
-
属性
- 属性只能在开始标签中,不能在结束标签中
- 必须使用引号,单/双引号都可以
- 同一个标签中可以有多个属性,但不能同名
- 属性名中不能有空格和冒号
-
注释
-
实体字符
-
不能使用特殊字符会与xml文件本身冲突,需使用转义字符
-
说明 字符 转义字符 小于 < & l t; 大于 > & g t; 双引号 " & q u o t; 单引号 ’ & a p o s; 与符号 & & a m p;
-
-
CDATA 字符数据区(可写特殊字符)
-
处理指令
-
<?xml version="1.0" encoding="UTF-8" ?> <?xml-stylesheet type="text/css" href="../css/xml.css" ?> <!-- 7.处理指令:导入外部的css样式控制xml的界面效果,没有啥用,xml不是为了展示好看的!--> <!-- 1.申明 抬头 必须在第一行--> <!-- 2.注释,本处就是注释,必须用前后尖括号围起来 --> <!-- 3.标签(元素),注意一个XML文件只能有一个根标签--> <student> <!-- 4.属性信息:id , desc--> <name id="1" desc="高富帅">西门庆</name> <age>32</age> <!-- 5.实体字符:在xml文件中,我们不能直接写小于号,等一些特殊字符 会与xml文件本身的内容冲突报错,此时必须用转义的实体字符。 --> <sql> <!-- select * from student where age < 18 && age > 10; --> select * from student where age < 18 && age > 10; </sql> <!-- 6.字符数据区:在xml文件中,我们不能直接写小于号,等一些特殊字符 会与xml文件本身的内容冲突报错,此时必须用转义的实体字符 或者也可以选择使用字符数据区,里面的内容可以随便了! --> <sql2> <![CDATA[ select * from student where age < 18 && age > 10; ]]> </sql2> </student>
文件约束
-
DTD(拓展名:.dtd)和Schema,开发中不需要自己写约束文件,了解会配置即可。
-
DTD缺点:不能验证数据类型
-
Schema特点
- 约束文件本身也是一个xml文件,它本身也会被其他xsd文档约束。
- 内置多种数据类型,可以检测数据类型是否正确。
- 支持命名空间,一个xml文件可以同时引入多个xsd的约束文件,让约束规则使用。
- 扩展名:xsd,XML Schema Definition
XML的解析
- DOM
- 思想:一次性把XML加载到内存中,称为Dom树,然后操作解析它。
- JAXP
- JDOM
- Dom4J(第三方公司研发的,性能优于JDOM,代码简单,高度面向对象)
- Jsoup
- 缺点:占内存。
- SAX
- 思想:一行一行的解析XML文件,基于事件驱动。
- 缺点:使用过的元素不能再次访问,只能查找不能修改。
DOM解析
-
xml文件document文档数对象DOM树
-
DOM4j中DOM树的API
组成 说明 Document 当前解析的XML文档对象 Node XML中节点,它是其它所有节点对象的父接口 Element 代表一个元素(标签) Attribute 代表一个属性 Text 代表标签中文本 -
dom4j属于第三方技术,必须导入该框架!!
-
dom4j安装步骤:
- a.去dom4j官网下载dom4j的框架:都是一些jar包。
- b.把dom4j的核心jar包导入到当前项目中去。
- c.在项目中创建一个文件夹:lib
- d.将dom4j-2.1.1.jar文件复制到 lib 文件夹
- e.在jar文件上点右键,选择 Add as Library -> 点击OK
- f.在类中导包使用
-
Java提供了Class下的一个方法:public InputStream getResourceAsStream(String path) – 用于加载文件成为一个字节输入流返回!!
dom4j获取根元素
-
Element getRootElement()
-
public static void main(String[] args) throws Exception { // 需求:解析books.xml文件成为一个Document文档树对象,得到根元素对象。 // 1.创建一个dom4j的解析器对象:代表整个dom4j框架。 SAXReader saxReader = new SAXReader(); // 2.第一种方式(简单):通过解析器对象去加载xml文件数据,成为一个Document文档树对象。 //Document document = saxReader.read(new File("Day13Demo/src/books.xml")); // 3.第二种方式(代码多点)先把xml文件读成一个字节输入流 // 这里的“/”是直接去src类路径下寻找文件。 InputStream is = Dom4JDemo01.class.getResourceAsStream("/books.xml"); Document document = saxReader.read(is); System.out.println(document); // 4.从document文档树对象中提取根元素对象 Element root = document.getRootElement(); System.out.println(root.getName()); }
dom4j获取子元素
-
String getName():取元素的名称。
-
List elements():获取当前元素下的全部子元素(一级)
-
List elements(String name):获取当前元素下的指定名称的全部子元素(一级)
-
Element element(String name):获取当前元素下的指定名称的某个子元素,默认取第一个(一级)
-
public static void main(String[] args) throws Exception { // 需求:解析books.xml文件成为一个Document文档树对象,得到根元素对象。 // 1.创建一个dom4j的解析器对象:代表整个dom4j框架。 SAXReader saxReader = new SAXReader(); // 2.第一种方式(简单):通过解析器对象去加载xml文件数据,成为一个Document文档树对象。 Document document = saxReader.read(new File("Day13Demo/src/books.xml")); // 3.获取根元素对象 Element root = document.getRootElement(); System.out.println(root.getName()); // 4.获取根元素下的全部子元素 List<Element> sonElements = root.elements(); for (Element sonElement : sonElements) { System.out.println(sonElement.getName()); } System.out.println("-------------------"); // 5.获取根源下的全部book子元素 List<Element> sonElements1 = root.elements("book"); for (Element sonElement : sonElements1) { System.out.println(sonElement.getName()); } System.out.println("-------------------"); // 6.获取根源下的指定的某个元素 Element son = root.element("user"); System.out.println(son.getName()); // 默认会提取第一个名称一样的子元素对象返回! Element son1 = root.element("book"); System.out.println(son1.attributeValue("id")); }
dom4j获取属性信息
-
List attributes(): 获取元素的全部属性对象。
-
Attribute attribute(String name):根据名称获取某个元素的属性对象。
-
String attributeValue(String var1):直接获取某个元素的某个属性名称的值。
-
Attribute对象的API:
- String getName(): 获取属性名称。
- String getValue(): 获取属性值。
-
public static void main(String[] args) throws Exception { // 1.创建一个dom4j的解析器对象:代表整个dom4j框架。 SAXReader saxReader = new SAXReader(); // 2.第一种方式(简单):通过解析器对象去加载xml文件数据,成为一个Document文档树对象。 Document document = saxReader.read(new File("Day13Demo/src/books.xml")); // 3.获取根元素对象。 Element root = document.getRootElement(); // 4.获取book子元素 Element bookEle = root.element("book"); // 5.获取book元素的全部属性对象 List<Attribute> attributes = bookEle.attributes(); for (Attribute attribute : attributes) { System.out.println(attribute.getName() + "=>" + attribute.getValue()); } // 6.获取Book元素的某个属性对象 Attribute descAttr = bookEle.attribute("desc"); System.out.println(descAttr.getName() + "--->" + descAttr.getValue()); // 7.可以直接获取元素的属性值 System.out.println(bookEle.attributeValue("id")); System.out.println(bookEle.attributeValue("desc")); }
Dom4j解析XML的文本
-
String elementText(String name): 可以直接获取当前元素的子元素的文本内容
-
String elementTextTrim(String name): 去前后空格,直接获取当前元素的子元素的文本内容
-
String getText():直接获取当前元素的文本内容。
-
String getTextTrim():去前后空格,直接获取当前元素的文本内容。
-
public static void main(String[] args) throws Exception { // 1.创建一个dom4j的解析器对象:代表整个dom4j框架。 SAXReader saxReader = new SAXReader(); // 2.第一种方式(简单):通过解析器对象去加载xml文件数据,成为一个Document文档树对象。 Document document = saxReader.read(new File("Day13Demo/src/books.xml")); // 3.获取根元素对象。 Element root = document.getRootElement(); // 4.得到第一个子元素book Element bookEle = root.element("book"); // 5.直接拿到当前book元素下的子元素文本值 System.out.println(bookEle.elementText("name")); System.out.println(bookEle.elementTextTrim("name")); // 去前后空格 System.out.println(bookEle.elementText("author")); System.out.println(bookEle.elementTextTrim("author")); // 去前后空格 System.out.println(bookEle.elementText("sale")); System.out.println(bookEle.elementTextTrim("sale")); // 去前后空格 // 6.先获取到子元素对象,再获取该文本值 Element bookNameEle = bookEle.element("name"); System.out.println(bookNameEle.getText()); System.out.println(bookNameEle.getTextTrim());// 去前后空格 }
XPath检索XML中的信息
-
引入:Dom4J可以用于解析整个XML的数据。但是如果要检索XML中的某些信息,建议使用XPath.
-
XPath使用步骤:
- 1.导入dom4j框架。(XPath依赖于Dom4j技术,必须先倒入dom4j框架!)
- 2.导入XPath独有的框架包。jaxen-1.1.2.jar
-
XPath常用API:
- List selectNodes(String var1):检索出一批节点集合。
- Node selectSingleNode(String var1):检索出一个节点返回。
-
XPath提供的四种检索数据的写法:
-
1.绝对路径,/根元素/子元素/子元素。
-
public void path01() throws Exception { // 1.创建一个dom4j的解析器对象:代表整个dom4j框架。 SAXReader saxReader = new SAXReader(); // 2.第二种方式(代码多点)先把xml文件读成一个字节输入流 // 这里的“/”是直接去src类路径下寻找文件。 InputStream is = Dom4JDemo01.class.getResourceAsStream("/Contact.xml"); Document document = saxReader.read(is); // 3.使用绝对路径定位全部的name名称 List<Node> nameNodes = document.selectNodes("/contactList/contact/name"); for (Node nameNode : nameNodes) { System.out.println(nameNode.getText()); } }
-
-
2.相对路径, ./子元素/子元素。 (.代表了当前元素)。
-
public void path02() throws Exception { // 1.创建一个dom4j的解析器对象:代表整个dom4j框架。 SAXReader saxReader = new SAXReader(); // 2.第二种方式(代码多点)先把xml文件读成一个字节输入流 // 这里的“/”是直接去src类路径下寻找文件。 InputStream is = Dom4JDemo01.class.getResourceAsStream("/Contact.xml"); Document document = saxReader.read(is); // 3.得到根元素对象 Element root = document.getRootElement(); // 4.从根元素开始检索 // .代表当前根元素对象路径!直接找其下的contact下的name List<Node> nameNodes = root.selectNodes("./contact/name"); for (Node nameNode : nameNodes) { System.out.println(nameNode.getText()); } }
-
-
3.全文搜索。
-
//元素 在全文找这个元素
-
//元素1/元素2 在全文找元素1下面的一级元素2
-
//元素1//元素2 在全文找元素1下面的全部元素2
-
public void path03() throws Exception { // 1.创建一个dom4j的解析器对象:代表整个dom4j框架。 SAXReader saxReader = new SAXReader(); // 2.第二种方式(代码多点)先把xml文件读成一个字节输入流 // 这里的“/”是直接去src类路径下寻找文件。 InputStream is = Dom4JDemo01.class.getResourceAsStream("/Contact.xml"); Document document = saxReader.read(is); // 3.//name是指在整个xml文件中检索name节点! List<Node> nameNodes = document.selectNodes("//name"); for (Node nameNode : nameNodes) { System.out.println(nameNode.getText()); } System.out.println("-----------------"); // 4.在全文中检索所有contact下的直接name节点 List<Node> nameNodes1 = document.selectNodes("//contact/name"); for (Node nameNode : nameNodes1) { System.out.println(nameNode.getText()); } System.out.println("-----------------"); // 5.在全文中检索所有contact下的所有name节点 List<Node> nameNodes2 = document.selectNodes("//contact//name"); for (Node nameNode : nameNodes2) { System.out.println(nameNode.getText()); } }
-
-
4.属性查找。
-
//@属性名称 在全文检索属性对象。
-
//元素[@属性名称] 在全文检索包含该属性的元素对象。
-
//元素[@属性名称**=**值] 在全文检索包含该属性的元素且属性值为该值的元素对象。
-
public void path04() throws Exception { // 1.创建一个dom4j的解析器对象:代表整个dom4j框架。 SAXReader saxReader = new SAXReader(); // 2.第二种方式(代码多点)先把xml文件读成一个字节输入流 // 这里的“/”是直接去src类路径下寻找文件。 InputStream is = Dom4JDemo01.class.getResourceAsStream("/Contact.xml"); Document document = saxReader.read(is); // 3.检索全部属性对象 List<Node> attributs = document.selectNodes("//@id"); for (Node attribut : attributs) { Attribute attr = (Attribute) attribut; System.out.println(attr.getName() + "--->" + attr.getValue()); } System.out.println("---------------"); // 4.//元素[@属性名称] 在全文检索包含该属性的元素对象 List<Node> nodeEles = document.selectNodes("//contact[@id]"); for (Node nodeEle : nodeEles) { System.out.println(nodeEle.getName()); } System.out.println("---------------"); // 5. //元素[@属性名称=值] 在全文检索包含该属性的元素且属性值为该值的元素对象。 Node nodeEle = document.selectSingleNode("//contact[@id=2]"); Element ele = (Element) nodeEle; System.out.println(ele.elementTextTrim("name")); }
-
-
工厂模式
-
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。
-
这种类型的设计模式属于创建型模式,它提供了一种创建对象的方式。
-
之前我们创建类对象时, 都是使用new 对象的形式创建, 除new 对象方式以外,工厂模式也可以创建对象.
-
工厂设计模式的作用:
- 1.对象通过工厂的方法创建返回,工厂的方法可以为该对象进行加工和数据注入。
- 2.可以实现类与类之间的解耦操作(核心思想,重点)
-
小结:
- 优点:工厂模式的存在可以改变创建对象的方式,解决类与类之间的耦合。
- 缺点:工厂设计模式多了一个工厂类!!!
-
public abstract class Animal { public abstract void run(); } public class Cat extends Animal { @Override public void run() { System.out.println("猫跑的贼溜~~~~"); } } public class Dog extends Animal { @Override public void run() { System.out.println("狗跑的也贼溜~~~~"); } } public class FactoryPattern { // 生产对象的方法:工厂方法 public static Animal createAniaml() { return new Cat(); } } public static void main(String[] args) { Animal a = FactoryPattern.createAniaml(); //若未来需要将业务改为狗,无需修改此处代码,直接修改工厂方法返回狗对象即可,其余所有对象都不需要改动,实现类的解耦 a.run(); }
装饰模式
-
装饰模式指的是在不改变原类, 动态地扩展一个类的功能。
-
思想:是创建一个新类,包装原始类,从而在新类中提升原来类的功能!!
-
装饰模式可以在不改变原类的基础上对类中的方法进行扩展增强,实现原则为:
- 1.定义父类。
- 2.定义原始类,继承父类,定义功能。
- 3.定义装饰类,继承父类,包装原始类,增强功能!!
-
public abstract class InputStream { public abstract void read(); public abstract void close(); } public class FileInputStream extends InputStream { @Override public void read() { System.out.println("读取数据~~~"); } @Override public void close() { System.out.println("关闭流~~~"); } } public class BufferedInputStrem extends InputStream { private InputStream is; public BufferedInputStrem(InputStream is) { this.is = is; } @Override public void read() { System.out.println("开启高效缓冲读取~"); is.read(); } @Override public void close() { is.close(); } } public static void main(String[] args) { InputStream is = new BufferedInputStrem(new FileInputStream()); is.read(); is.close(); }
Commons-io包的使用介绍
- commons-io是apache开源基金组织提供的一组有关IO操作的类库,
- 可以挺提高IO功能开发的效率。commons-io工具包提供了很多有关io操作的类,
- 见下表:
包 | 功能描述 |
---|---|
org.apache.commons.io | 有关Streams、Readers、Writers、Files的工具类 |
org.apache.commons.io.input | 输入流相关的实现类,包含Reader和InputStream |
org.apache.commons.io.output | 输出流相关的实现类,包含Writer和OutputStream |
- 步骤:
- 下载commons-io相关jar包;http:*//commons.apache.org/proper/commons-io/
- 把commons-io-2.6.jar包复制到指定的Module的lib目录中
- 将commons-io-2.6.jar加入到classpath中
- 小结:IOUtils和FileUtils可以方便的复制文件和文件夹!!
public static void main(String[] args) throws Exception {
// 1.完成文件复制!
IOUtils.copy(new FileInputStream("Day13Demo/src/books.xml"), new FileOutputStream("Day13Demo/new.xml"));
// 2.完成文件复制到某个文件夹下!
FileUtils.copyFileToDirectory(new File("Day13Demo/src/books.xml"), new File("D:/itcast"));
// 3.完成文件夹复制到某个文件夹下!
FileUtils.copyDirectoryToDirectory(new File("D:\\itcast\\约吧图片服务器"), new File("D:\\"));
// Java从1.7开始提供了一些nio, 自己也有一行代码完成复制的技术。
Files.copy(Paths.get("Day13Demo/src/books.xml")
, new FileOutputStream("Day13Demo/new11.txt"));
}
base64
Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。
在Java 8中,Base64编码已经成为Java类库的标准。
Java 8 内置了 Base64 编码的编码器和解码器。
Base64工具类提供了一套静态方法获取下面三种BASE64编解码器:
- **基本:**输出被映射到一组字符A-Za-z0-9+/,编码不添加任何行标,输出的解码仅支持A-Za-z0-9+/。
- **URL:**输出映射到一组字符A-Za-z0-9+_,输出是URL和文件。
- **MIME:**输出隐射到MIME友好格式。输出每行不超过76字符,并且使用’\r’并跟随’\n’作为分割。编码输出最后没有行分割。
Base64内嵌类和方法描述
内嵌类
序号 | 内嵌类 & 描述 |
---|---|
1 | static class Base64.Decoder该类实现一个解码器用于,使用 Base64 编码来解码字节数据。 |
2 | static class Base64.Encoder该类实现一个编码器,使用 Base64 编码来编码字节数据 |
方法
序号 | 方法名 & 描述 |
---|---|
1 | **static Base64.Decoder getDecoder()**返回一个 Base64.Decoder ,解码使用基本型 base64 编码方案。 |
2 | **static Base64.Encoder getEncoder()**返回一个 Base64.Encoder ,编码使用基本型 base64 编码方案。 |
3 | **static Base64.Decoder getMimeDecoder()**返回一个 Base64.Decoder ,解码使用 MIME 型 base64 编码方案。 |
4 | **static Base64.Encoder getMimeEncoder()**返回一个 Base64.Encoder ,编码使用 MIME 型 base64 编码方案。 |
5 | **static Base64.Encoder getMimeEncoder(int lineLength, byte[] lineSeparator)**返回一个 Base64.Encoder ,编码使用 MIME 型 base64 编码方案,可以通过参数指定每行的长度及行的分隔符。 |
6 | **static Base64.Decoder getUrlDecoder()**返回一个 Base64.Decoder ,解码使用 URL 和文件名安全型 base64 编码方案。 |
7 | **static Base64.Encoder getUrlEncoder()**返回一个 Base64.Encoder ,编码使用 URL 和文件名安全型 base64 编码方案。 |
**注意:**Base64 类的很多方法从 java.lang.Object 类继承。
代码演示
public static void main(String args[]) {
try {
// 1-1.基本编码后结果。普通文本的编码
String rs1 = Base64.getEncoder().encodeToString("黑马程序员".getBytes());
System.out.println(rs1); // 6buR6ams56iL5bqP5ZGY
// 1-2.基本解码后结果。普通文本的解码
byte[] buffer = Base64.getDecoder().decode(rs1);
System.out.println(new String(buffer));
// 2-1.URL编码
String rs2 = Base64.getUrlEncoder().encodeToString("?loginName=黑马&passWord=123456".getBytes());
System.out.println(rs2);
// 2-2 URL解码
byte[] buffer2 = Base64.getUrlDecoder().decode(rs2);
System.out.println(new String(buffer2));
// 3-1 MIME编码
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10; ++i) {
sb.append(UUID.randomUUID().toString());
}
String rs3 = Base64.getMimeEncoder().encodeToString(sb.toString().getBytes());
System.out.println(rs3);
// 3-2 MIME解码
byte[] buffer3 = Base64.getMimeDecoder().decode(rs3);
System.out.println(new String(buffer3));
} catch (Exception e) {
System.out.println("Error :" + e.getMessage());
}
}
ps:b站课程《黑马程序员Java13天进阶》根据官方笔记结合自身情况整理的笔记
视频链接