XML
1.xml文件
- XML全称是Extensible Markup Language,是一种可扩展的标记语言,使用标签来描述数据,并且标签可以自定义
- 作用是存储、传输数据或者用于软件配置文件
- xml标签
- 标签由尖括号和合法标识符组成
- 标签必须成对出现,有些特殊的标签不成对但是必须有结束标记,如
<student></student>
、</adderss>
- 标签中可以定义属性,属性和标签名用空格隔开,属性值需要用双引号引起来,如
<student id="1"></student>
- 一个xml文件有且仅有一个根标签,标签需要正确嵌套
- 语法规则
- 文件后缀名是.xml
- 文档声明必须是文件第一行第一列,格式如下
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
version属性:必选的
encoding属性:可选的,指定打开该文件时使用的字符编码表,一般是UTF-8
standalone属性:可选的,指定该xml文件是否依赖其他的的xml文件,取值为yes/no - xml文件中的注释语法是
<!--注释信息-->
- 五种特殊字符的表示
xml中的表示 |
字符 |
说明 |
< |
< |
小于号 |
> |
> |
大于号 |
& |
& |
与号 |
' |
'' |
单引号 |
" |
"" |
双引号 |
- xml文件中的CDATA区,语法是
<![CDATA[内容]]>
内容部分只会被当作文本看待 - DOM解析思想
- DOM(Document Object Model)是文档对象模型,将文档各个部分看成对应的对象
- 将xml文件加载到内存中,形成一个树形结构,再获取对应的值
- 范例
<?xml version="1.0" encoding="UTF-8" ?> <students> <student id="1"> <name>张三</name> <age>18</age> </student> <student id="2"> <name>李四</name> <age>20</age> </student> </students> 该文档的树结构为 Document对象:表示整个文档 Element对象:表示所有的标签 Attribute对象:表示所有属性 Text对象:表示所有文本内容 a. 常用xml解析工具:DOM4J,需引入jar包
2.约束
- 约束用于限定xml文件中可以使用的标签以及属性
- DTD约束
- 引入DTD约束的方式
- 引入本地DTD
<!DOCTYPE 根元素名称 SYSTEM 'DTD文件路径'>
- 在xml文件内部引入
<!DOCTYPE 根元素名称 [DTD文件内容]>
- 引入网络中的DTD
<!DOCTYPE 根元素名称 PUBLIC "DTD文件名称" "DTD文档的URL">
- DTD文档中语法规则
- 定义元素
语法:<!ELEMENT 元素名 元素类型>
元素类型分为简单元素,复杂元素
- 简单元素取值可以是:
EMPTY
、ANY
、PCDATA
,分别表示标签体为空、可以为空可以不为空、元素内容部分为字符串 - 复杂元素则需要将该元素中的所有元素列出,规则是:
多个元素使用,
或|
隔开,,
表示定义子元素的顺序,|
表示子元素只能出现任意一个
在子元素后面使用?
,+
,*
分别可以指定子元素出现的次数是零次或一次,一次或多次,零次或多次
如果不写则表示一次
范例:
<!ELEMENT students (student+)> <!ELEMENT student (name,age)> <!ELEMENT name (#PCDATA)> <!ELEMENT age (#PCDATA)>
- 定义属性
语法:<!ATTLIST 元素名称 属性名称 属性类型 属性约束>
元素名称:指出该属性属于哪个元素
属性名称:指出属性的名称
属性类型:CDATA
表示普通的字符串
属性约束:有三个常用取值REQUIRED
、IMPLIED
、FIXED value
,分别表示必需的、非必需的、固定值的(value是指出的固定值)
范例:
<!ATTLIST student id CDATA #REQIRED>
- schema约束
- 内容仅仅了解,没做总结
Servlet技术
一.Servlet
1.概述
- Servlet是运行在web服务器端的应用程序,使用Java语言编写
- Servlet对象主要封装了对HTTP请求的处理,它的运行需要Servlet容器(如Tomcat)的支持
- Servlet由Servlet容器进行管理,Servlet容器将Servlet动态加载到服务器上,与HTTP协议相关的Servlet使用HTTP请求和HTTP响应与客户端进行交互
- 如下图,Servlet的请求首先会被HTTP服务器(如Apache)接收,HTTP服务器只负责静态HTML界面的解析,而Servlet的请求则转交给Servlet容器,Servlet容器会根据请求路径以及Servlet之间的映射关系,调用相应的Servlet,Servlet将处理的结果返回给Servlet容器,并通过HTTP服务器将响应传输给客户端
graph LR;
A[客户端] --> |HTTP请求| B[HTTP服务器]
B --> C[Servlet容器]
C --> D[Servlet]
D --> C
C --> B
B --> |HTTP响应| A
2.Servlet接口
- Servlet就是实现了Servlet接口的类,它由Web服务器创建并调用,用于接收和响应用户的请求,在Servlet接口中定义了五个抽象方法
方法声明 |
说明 |
void init(ServletConfig config) |
Servlet实例化后,Servlet容器调用该方法完成Servlet的初始化工作 |
ServletConfig getServletConfig() |
获取Servlet对象的配置信息 |
String getServletInfo() |
返回包含Servlet信息的字符串,如作者,版权等 |
void service(ServletRequest req,ServletResponse resp) |
负责响应用户的请求,当容器接收到客户端访问Servlet对象的请求时就会调用此方法。容器会构造一个表示客户端请求信息的ServletRequest对象和一个用于响应客户端的ServletResponse对象作为参数传递给service()方法,在service()方法中可以通过ServletRequest对象得到客户端的相关信息和请求信息,在对请求进行处理后,调用ServletResponse对象的方法设置相应信息 |
void destroy() |
负责释放Servlet对象占用的资源,当服务器关闭或者Servlet对象被移除时会销毁Servlet对象,此时会调用此方法 |
- 编写的Servlet类必须实现Servlet接口或者继承Servlet接口的实现类,如GenericServlet和HttpServlet,这两个类都是抽象类并且HttpServlet继承了GenericServlet,其中GenericServlet有一个抽象方法service(),而HttpServlet没有抽象方法
- 总结三种方式编写Servlet类
- 实现Servlet接口,需要重写Servlet接口里边的所有方法
- 继承GenericServlet抽象类,必须重写service()方法,其他方法也可以重写
- 继承HttpServlet抽象类,不需要重写service()方法,因为HttpServlet在service()方法中调用了另一个重载的service()方法,这个重载的方法里边会根据参数选择相应的方法,如doGet()方法或doPost()方法,所以我们编写时可以重写doGet()方法和doPost()方法来实现我们想要的功能
- 通常情况下使用继承HttpServlet抽象类的方式编写Servlet
- 实例
public class ServletDemo02 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("方法执行了"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
- Servlet线程安全问题:在实现Servlet的类中如果存在自定义的成员变量,并且在service()方法中操作这个变量时可能会出现线程安全问题,解决的办法是将成员变量改为定义在方法内部的局部变量,或者使用sychronized锁
- HttpServlet常用方法
方法 |
说明 |
protected void doGet(HttpServletRequest req,HttpServletResponse resp) |
用户处理GETl类型的HTTP请求 |
protected void doPost(HttpServletRequest req,HttpServletResponse resp) |
用于处理POST类型的HTTP请求 |
protected void doPut(HttpServletRequest req,HttpServletResponse resp) |
用于处理PUT类型的HTTP请求 |
- 关系视图
网络异常,图片无法展示|
3.Servlet生命周期
- 生命周期图示
网络异常,图片无法展示| - Servlet生命周期大致分为三个阶段,分别是初始化阶段、运行阶段、销毁阶段
- 初始化阶段:
当客户端向Servlet容器发出HTTP请求访问Servlet时,Servlet容器首先解析请求,检查内存中是否已经有了该Servlet对象,如果有,直接使用该Servlet对象;如果没有,就创建Servlet实例对象,然后通过调用init()方法完成Servlet初始化。需要注意,在Servlet整个生命周期内,它的init()方法只被调用一次 - 运行阶段:
Servlet容器会为客户端请求创建代表HTTP请求的ServletRequest对象和代表HTTP响应的ServletResponse对象,然后将它们作为参数传递给Servlet的service()方法。service()方法从ServletRequest对象中获取客户端请求并处理该请求,通过ServletResponse对象生成响应结果。在Servlet整个生命周期内,对于Servlet的每一次访问请求,Servlet容器都会调用一次Servlet的service()方法,并且创建新的ServletRequest和ServletResponse对象。即service()方法在Servlet整个生命周期中会被调用多次 - 销毁阶段
当服务器关闭或者Web应用被移除出容器时,Servlet随着Web应用的销毁而销毁。在销毁Servlet之前,Servlet容器会调用Servlet的destroy()方法,以便让Servlet对象释放它所占用的资源。在Servlet的整个生命周期中,destroy()方法也只被调用一次。注意,Servlet对象一旦创建就会驻留在内存中等待客户端的访问,直到服务器关闭或Web应用被移除出容器时Servlet对象才会销毁
4.Servlet配置
- 使用web.xml配置Servlet
- 在web.xml文件中,通过
<servlet></servlet>
标签进行注册,<servlet>标签下包含若干个子元素,功能如下
元素 |
类型 |
描述 |
<servlet-name></servlet-name> |
String |
指定Servlet名称,一般与Servlet类同名,要求唯一 |
<servlet-class></servlet-class> |
String |
指定Servlet位置,一般是全类名 |
<description></description> |
String |
指定Servlet的描述信息 |
<display-name></display-name> |
String |
指定Servlet的显示名 |
- 把Servlet映射到URL地址,使用
<servlet-mapping></servlet-mapping>
进行映射,在<servlet-mapping>元素下使用<servlet-name></servlet-name>
指出Servlet的名称,需要和之前在<servlet>标签下注册的相同;使用<url-pattern></url-pattern>
映射URL地址,地址前必须添加/ - 实例
<servlet> <!--指出Servlet名称--> <servlet-name>ServletDemo01</servlet-name> <!--指出Servlet全类名--> <servlet-class>com.demo.ServletDemo01</servlet-class> </servlet> <servlet-mapping> <!--和servlet标签下的名称一致--> <servlet-name>ServletDemo01</servlet-name> <!--映射地址,必须加斜杠--> <url-pattern>/ServletDemo01</url-pattern> </servlet-mapping>
- 使用注解配置Servlet
- @WebServlet 注解用于代替web.xml文件中的
<servlet>
、<servlet-mapping>
等标签,该注解会在项目部署时被容器处理,容器会根据具体的属性配置将相应的类部署为Servlet,@WebServlet注解常用属性如下 - 常用属性
属性声明 |
功能 |
String name |
指定Servlet的name属性,等价于<servlet-name>,如果没有显式指定则取值为类的全限定名 |
String[] value |
等价于<url-pattern> |
String[] urlPatterns |
和value功能一样,value和urlPatterns不能同时使用 |
int loadOnStartup |
指定Servlet的加载时机,等价于<load-on-startup> |
WebInitParam[] initParams |
指定一组Servlet初始化参数,等价于<init-param>,其中WebInitParam也是一种注解 |
- 实例
@WebServlet(name = "ServletDemo01",urlPatterns = "/ServletDemo01",initParams = {@WebInitParam(name = "encoding",value = "UTF-8"),@WebInitParam(name = "desc",value = "this is ServletDemo01")}) public class ServletDemo01 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("ServletDemo01运行了"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
5.Servlet创建时机
- 第一次访问时创建
优势:减少服务器内存的浪费
弊端:如果有一些需要在应用加载时就做的初始化操作,无法完成 - 服务器加载时创建
优势:提前创建好对象,提高首次执行时的效率,可以完成一些应用加载时要做的初始化工作
弊端:对服务器内存占用较多,影响服务器启动效率 - 修改Servlet创建时机:在web.xml文件的<servlet>标签中添加
<load-on-startup></load-on-startup>
标签,标签中间填写的是整数,正整数表示在服务器加载时创建,值越小优先级越高,负整数或者不填表示第一次访问时创建
6.默认Servlet
- 默认Servlet是服务器提供的一个Servlet,它配置在Tomcat的conf目录中的web.xml文件中
- 它的映射路径是
<url-pattern>/</url-pattern>
,在接收请求时,首先会在项目中的web.xml文件查找映射配置,找到则执行,找不到时再去找默认的Servlet,由默认Servlet处理
二.ServletConfig
1.概述
- ServletConfig是一个接口
- 当Tomcat初始化一个Servlet时,会将该Servlet的配置信息封装到一个ServletConfig对象中,通过调用init(ServletConfig config)方法将ServletConfig对象传递给Servlet,ServletConfig的生命周期与Servlet一样
- ServletConfig封装的配置信息是键值对的形式
- 常用方法
方法 |
说明 |
String getInitParameter(String name) |
根据参数名返回对应的参数值 |
Enumeration getInitParameterNames() |
返回一个Enumeration对象,其中包含了所有的参数名 |
ServletContext getServletContext() |
返回代表当前web应用的ServletContext对象 |
String getServletName() |
返回Servlet的名称 |
2.ServletConfig配置
- 配置ServletConfig也是在web.xml文件中的
<servlet></servlet>
标签下进行的,需要使用<init-param></init-param>
标签将参数名和参数值包住,表示一个键值对,其中使用<param-name></para-name>
表示参数名,<param-value></param-value>
表示参数值 - 一个
<init-param></init-param>
只能表示一个键值对 - 范例
<servlet> <servlet-name>ServletConfigDemo</servlet-name> <servlet-class>com.liaoxiangqian.ServletConfigDemo</servlet-class> <!--配置encoding参数,使用一个init-param标签--> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <!--配置desc参数,使用一个init-param标签--> <init-param> <param-name>desc</param-name> <param-value>this is ServletConfigDemo</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>ServletConfigDemo</servlet-name> <url-pattern>/ServletConfigDemo</url-pattern> </servlet-mapping>