day12
XML
xml的简介
- 可扩展标记语言(EXtensible Markup Language),XML 它是一种标记语言,很类似 HTML,标签都是自定义的。 如: < user > < /user > 或 < student>
< /student> - W3C在1988年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是展示数据
作用
-
(1)配置文件 (配置文件)
-
(2)存储数据
-
(3)数据传输 json
xml的特殊字符
XML的组成
- <?xml version="1.0" encoding="UTF-8"?>
- 1.文档声明必须为 <?xml开头,以?> 结束;
- 2.文档声明必须从文档的0行0列位置开始;
- 3.文档声明只有2个属性:
-
< bean></ bean>元素 element
-
1.元素是XML文档中最重要的组成部分,
-
2.元素的由开始标签、元素体、结束标签组成。例如: < hello>大家好</ hello>
-
3.元素体:元素体可以是元素,也可以是文本,例如: < b>< a >你好</ a>< /b>
-
4.空元素:空元素只有开始标签,而没有结束标签,但元素必须自己闭合,例如: < c />
-
5.元素命名:
- 1.区分大小写
- 2.不能使用空格,不能使用冒号:
- 3.不建议以XML、xml、Xml开头 < xml></ xml>
-
6.格式化良好的XML文档,必须只有一个根元素。
-
-
属性 attribute 比如: < bean id="" className="" myscore="">
- 1.属性是元素的一部分,它必须出现在元素的开始标签中
- 2.属性的定义格式:属性名=属性值,其中属性值必须使用单引或双引
- 3.一个元素可以有0~N个属性,但一个元素中不能出现同名属性
- 4.属性名不能使用空格、冒号等特殊字符,且必须以字母开头
xml的解析
-
XML的约束(了解)
-
规范,规范我们的标签以及属性。 dtd 约束 schema约束
-
dtd约束是一个比较老的一个约束。相对来说学习比较简单 学习成本低
- bean-dtd.xml
- bean-dtd.dtd
-
schema约束是一个新的约束 比较复杂(很复杂)学习成本高
-
-
常见的解析方式
-
解析方式
-
1.DOM:要求解析器把整个XML文档装载到内存,并解析成一个Document对象。(DOM树)
- 优点:元素与元素之间保留结构关系,故可以进行增删改查操作。
- 缺点:XML文档过大,可能出现内存溢出显现。
-
2.SAX:是一种速度更快,更有效的方法。它逐行扫描文档,一边扫描一边解析。并以事件驱动的方式进行具体解析,每执行一行,都将触发对应的事件。(了解)
- 优点:处理速度快,可以处理大文
- 缺点:只能读,逐行后将释放资源。
-
-
-
dom解析原理和结构模型
- 原理: XML DOM 将整个XML文档加载到内存,生成一个DOM树,并获得一个Document对象,通过Document对象就可以对DOM进行操作
-
dom操作步骤:
dom 解析-
1.第一步也就是需要把xml转换成一个dom树
- 具体的步骤 :
- 1.得到解析器工厂对象DocumentBuilderFactory
- 2.得到解析器对象
- 3.调用其方法把其转换成doc 对象 db.parse(file); 需要传递一个文件对象的参数
- 具体的步骤 :
-
2.得到xml的信息:
- 1.根据getElementsByTagName()方法来获取到 所有的brand节点
- 2.遍历集合(NoteList) 获取集合的长度是getLength()
- 3.得到具体的节点
- 4.转换为元素节点 获取元素中具体的值 getAttribute(“name”)
- 5.获取下面的子节点:getChildNodes();
- 6.注意:判断其节点的类型 Node.ELEMENT_NODE
-
3.增加阶段的具体步骤:
- 1.创建一个节点
- 2.设置其属性
- 3.添加父子关系
- 4.一层一层添加之后追加到根节点
-
4 保存到xml里 :
- 1.得到其转换的工厂TransformerFactory
- 2.得到准换器Transformer
- 3.调用其方法 tf.transform() 需要传递两个参数
- 3.1第一个是DOMSource(不要忘记把dom对象放入) 第二个参数是:StreamResult
-
5.删除操作 :
- 1.根据getElementsByTagName()方法来获取到 所有的brand节点
- 2.遍历集合(NoteList) 获取集合的长度是getLength()
- 3.通过父节点来删除自己
-
6.修改与删除是类似
-
DOM4J 的 API使用
-
DOM4J是一个Java的XML API,具有性能优异、功能强大和极其易使用的特点,它的性能超过sun公司官方的dom技术,如今可以看到越来越多的Java软件都在使用DOM4J来读写XML。如果想要使用dom4j,需要引入支持dom4j的jar包 dom4j-1.6.1.jardom4j 必须使用核心类SaxReader加载xml文档获得Document,通过Document对象获得文档的根元素,然后就可以操作了。
-
常用API
-
1.SaxReader对象
- read(…) 加载执行xml文档
-
2.Document对象
- getRootElement() 获得根元素
-
3.Element对象 方法:
- 1 elements(…) 获得指定名称的所有子元素。可以不指定名称
- 2 element(…) 获得指定名称第一个子元素。可以不指定名称
- 3 getName() 获得当前元素的元素名
- 4 attributeValue(…) 获得指定属性名的属性值
- 5 elementText(…) 获得指定其子元素 的文本值
- 6 getText() 获得当前元素的文本内容
- 7 addElement(“Brand”); 创建一个节点的对象
- 8 elementIterator() 把多个集合转换成迭代器
- 9 elBrand.getParent().remove(elBrand); 通过父节点来删除子节点
-
-
API案例实现
/**
*
*/
package com.ujiuye.demo1;
import java.lang.reflect.Constructor;
import java.util.List;
import javax.crypto.Cipher;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
* @author: t c y
* @date:2019年11月12日
* @Copyright:
*/
public class QueryXmlDom {
//本类为测试xml dom的使用示例
/*
* 使用步骤:
* 1、导包
* dom4j-1.6.1.jar
* 2、配置xml
* 3、新建SAXReader类得到该类对象。
* 4、调用该类读的方法并输入xml所在路径 read("src/student.xml") 返回的是一个Document对象
* 5、调用Document对象的获取根节点方法 getRootElement() 返回的是Element对象。
* 6、执行操作:
* element("name") 是获取所在节点下指定名称的单个子节点的方法。返回的是一个Element对象
* 如果存在多个,则会获取第一个
* elements("bean"); 是获取所在节点下 指定名称的所有子节点 。返回的是一个带Element泛型的List集合。
* 泛型需要自己确定。
* getText():获取的是当前节点的文本值
* elementText() 获取指定名称的子节点的文本值
* attributeValue("class"); 获取所在节点上的属性名对应的的属性值
* getName() 获取标签(元素)名称
*
*/
public static void main(String[] args) throws Exception {
SAXReader reader = new SAXReader();
Document document = reader.read("src/student.xml");
Element rootElement = document.getRootElement();
List<Element> elements = rootElement.elements("student");
for (Element student : elements) {
Element stuname = student.element("name");
String xing = stuname.elementText("xing");
String ming = stuname.elementText("ming");
String id = stuname.attributeValue("id");
String name = stuname.getText();
String age = student.element("age").getText();
String sex = student.element("sex").getText();;
if (xing!=null &&ming!=null) {
name=xing+ming;
}
Student stu = new Student(id,name,Integer.parseInt(age),sex);
System.out.println(stu);
}
}
}
student.xml文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!--
注释: xml文件开头必须以该开头 <?xml version="1.0" encoding="UTF-8" ?>
或者是以命名规则的开头 <!DOCTYPE beans SYSTEM "bean-dtd.dtd">
-->
<students>
<student number="offcn_0001">
<name id="youjiuye">
<xing>张</xing>
<ming>三</ming>
</name>
<age>18</age>
<sex>male</sex>
</student>
<student number="offcn_0002">
<name>jack</name>
<age>18</age>
<sex>female</sex>
</student>
<student number="offcn_0003">
<name id="itoffcn">
<xing>李</xing>
<ming>四</ming>
</name>
<age>20</age>
<sex>male</sex>
</student>
</students>
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里面Document对象提供了两个API方法,用来支持 xpath表达式
- List selectNodes(“xpath表达式”),用来获取多个节点
- Element 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
-
package com.offcn.utils;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
//本类为使用XPath类示例:
/*
* 1、导包
* dom4j-1.6.1.jar
jaxen-1.1-beta-6.jar
* 2、配置xml
* 3、新建SAXReader类得到该类对象。
* 4、调用该类读的方法并输入xml所在路径 read("src/student.xml") 返回的是一个Document对象
* 5、调用Document对象的获取根节点方法 getRootElement() 返回的是Element对象。
* 6、调用Element对象的方法
* selectSingleNode("//name[@id]/xing") 获取符合的单个节点 返回的类型需要强转为Element,用Element对象接收
* selectNodes("//name[@id]/xing") 获取符合的所有节点
*/
/*结合xpath语法查询
查询所有student标签
查询所有student标签下的name标签
查询student标签下带有id属性的name标签
查询student标签下带有id属性的name标签 并且id属性值为youjiuye*/
public class XpathDemo {
public static void main(String[] args) throws Exception {
//创建解析式
SAXReader reader = new SAXReader();
//把当前文档加载到内存
Document document = reader.read("src/Student.xml");
//获取跟节点
Element rootElement = document.getRootElement();
// 查询所有student标签
List<Element> nodes = rootElement.selectNodes("//student");
// 查询所有student标签下的name标签
List<Element> list = rootElement.selectNodes("//student/name");
// 查询student标签下带有id属性的name标签
List<Element> selectNodes = rootElement.selectNodes("//student/name[@id]");
// 查询student标签下带有id属性的name标签 并且id属性值为youjiuye
List<Element> nodes2 = rootElement.selectNodes("//student/name[@id='youjiuye']");
for (Element element : nodes2) {
System.out.println(element.attributeValue("id"));
}
List<Element> nodes3 = rootElement.selectNodes("//student/name/xing");
for (Element element : nodes3) {
if(element.getText().equals("张")) {
System.out.println(element.getText());
}
}
}
}
案例
-
student.xml
- student.xml
-
编写xpath代码解析xml文件
- 结合xpath语法查询
- 查询所有student标签
- 查询所有student标签下的name标签
- 查询student标签下带有id属性的name标签
- 查询student标签下带有id属性的name标签 并且id属性值为youjiuye
HTTP协议
概述
- 超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。用
于定义WEB浏览器与WEB服务器之间交换数据的过程。
Http协议的作用及特点
- HTTP协议的特点
HTTP默认的端口号为80,HTTPS的端口号为443。-
基于请求/响应模型的协议。
- 请求和响应必须成对;
- 先有请求后有响应。
-
简单快捷
- 因为发送请求的时候只需要发送请求方式和请求路径即可
-
曾经学过的协议:TCP、UDP
Http版本介绍
-
1.0
- 发送请求,创建一次连接,获得一个web资源,连接断开。
-
1.1
- 发送请求,创建一次连接,获得多个web资源,连接断开。
HTTP协议有两种报文格式
- 请求报文:由客户端向服务器端发出的报文。
- 响应报文:从服务端到客户端的报文
Http请求报文详解
- 由客户端向服务器端发出的报文
- HTTP请求报文格式:包含请求行、请求头、空行、请求体 四个部分
- get :传递的参数在放在请求头上 不安全 get 与一般用于文件的下载 get提交数据是有长度限制
- post 传递到参数是放下内容体中 安全性高 post 提交数据 post 是没有长度限制的
Http响应详解
- 响应报文:从服务端到客户端的报文。
- HTTP响应报文格式:
- 响应行、响应头、空行、响应体 四个部分
- 响应行、响应头、空行、响应体 四个部分
请求响应图示
- 请求
- 响应
- 未完续
响应的状态码
- 200:请求响应成功
- 302:重新定向
- 304:缓存数据
- 404:路径错误。(用户地址写错了)
- 500:服务器端错误(告诉你代码写错了。)【5xx】
实操
package com.ujiuye.demo;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Arrays;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import com.mchange.v2.c3p0.ComboPooledDataSource;
/**
* @author: t c y
* @date:2019年11月12日
* @Copyright:
*/
public class RegisterServlet implements Servlet {
//本类为测试form表单注册类:
/*
* 使用步骤:
* 1、导包: 本次使用c3p0连接池和DButils工具 mysql数据库驱动
* c3p0-0.9.2.1.jar
* commons-dbutils-1.4.jar
* mchange-commons-java-0.2.3.4.jar
* mysql-connector-java-5.1.40-bin.jar
* 2、新建数据库新建表 初始化数据。
* 3、新建网页html,新建表单form
* 4、新建servlet中间件 java类
* 5、在配置文件里面注册 该类,并指定路径。
*/
ComboPooledDataSource datasource=new ComboPooledDataSource("mysql");
QueryRunner queryRunner=new QueryRunner(datasource);
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
// TODO Auto-generated method stub
HttpServletRequest request=(HttpServletRequest)req;
HttpServletResponse response=(HttpServletResponse)res;
response.setContentType("text/html; charset=UTF-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
String sex = req.getParameter("sex");
String[] hobby = req.getParameterValues("hobby");
try {
String sql="select COUNT(*) from user where username=?;";
Long count =(Long)queryRunner.query(sql, new ScalarHandler(),username);
if (count>0) {
response.getWriter().print("用户已存在");
System.out.println("用户已存在!!");
request.getRequestDispatcher("/WEB-INF/html/faile.html").forward(request, response);
return;
}else {
sql="insert into USER(username,password,sex,hobby) values(?,?,?,?)";
int row = queryRunner.update(sql,username,password,sex,Arrays.toString(hobby));
//转发
request.getRequestDispatcher("/WEB-INF/html/success.html").forward(request, response);
System.out.println("受影响的行数有:"+row);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
}
@Override
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
return null;
}
@Override
public String getServletInfo() {
// TODO Auto-generated method stub
return null;
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}