XML
XML就是一种数据的描述语言,虽然它是语言,但是通常情况下,它并不具备常见语言的基本功能——被计算机识别并运行。只有依靠另一种语言,来解释它,使它达到你想要的效果或被计算机所接受。
示例⬇
<?xml version="1.0" encoding="UTF-8"?>
<hello version="1.0" id="1">
<a></a>
<c><<!-- 使用转义符代替小于号大于号等等 -->AAAA</c>
<b>
<!-- CDATA不会被解析,出现大量的转义符出现在XML文档中时,会大幅降低可读性,
CDATA段中出现的字符无需使用转义字符替代,为了避免频繁使用转义符可以使用CDATA -->
<![CDATA[
if(a>b&&b<c){}
]]>
</b>
</hello>
DTD约束
给XML加以约束
DTD约束的引用方法(一般放在XML头下)
1.内部DTD,在XML文档内部嵌入DTD,只对当前XML有效
2.外部DTD-本地DTD,DTD文档在本地系统上,公司内部自己项目使用
3.外部DTD-公共DTD,DTD文档在网络上,一般都有框架提供。
注意:一般使用框架提供的DTD,不需要自己编写,只要能够读懂就足够了
案例实现
DTD文件中属性类型的选项
DTD约束文件
<?xml version="1.0" encoding="UTF-8"?>
<!--
模拟serblet2.3规范,如果开发人员需要在xml使用当前DTD约束,必须包括DOCTYPE。
格式如下:
<!DOCTYPE web-app SYSTEM "web-app_2_3.dtd">
-->
<!ELEMENT web-app (servlet*,servlet-mapping*,welcome-file-list?)>
<!ELEMENT servlet (servlet-name,description?,(servlet-class|jsp-file))>
<!ELEMENT servlet-mapping (servlet-name,url-pattern+)>
<!-- #PCDATA为只能出现文本 -->
<!ELEMENT servlet-name (#PCDATA)>
<!ELEMENT servlet-class (#PCDATA)>
<!ELEMENT url-pattern (#PCDATA)>
<!ELEMENT description (#PCDATA)>
<!ELEMENT jsp-file (#PCDATA)>
<!ELEMENT welcome-file-list (welcome-file+)>
<!ELEMENT welcome-file (#PCDATA)>
<!ATTLIST web-app version CDATA #IMPLIED>
使用DTD配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app SYSTEM "web-app_2_3.dtd">
<web-app version="1.0">
<servlet>
<servlet-name>aynor</servlet-name>
<servlet-class>xxxxxxxxxx</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>aynor</servlet-name>
<url-pattern>hello</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file></welcome-file>
</welcome-file-list>
</web-app>
Schema约束
比DTD强大的多,是DTD的替代者,支持名称空间
XML解析
一共三种解析方式,四种解析开发包
使用Dom4j对XML进行解析(需要导入jar包,这里用的是dom4j-1.6.1.jar)
package cn.aynortechnology.xml.dom4j;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;
public class TestDom4j {
@Test
public void testReadWebXML() {
try {
//1.获取解析器
SAXReader saxReader = new SAXReader();
//2.获取document文档对象
Document doc = saxReader.read("src/cn/aynortechnology/xml/dtd/web.xml");
//3.获取根元素
Element rootElement = doc.getRootElement();
//System.out.println(rootElement.getName());//获取根元素名称
//System.out.println(rootElement.attributeValue("version"));//获取根元素中的属性值
//4.获取根元素下的子元素
List<Element> childElements = rootElement.elements();
//5.遍历子元素
for (Element element : childElements) {
//6.判断元素名称为servlet的元素
if("servlet".equals(element.getName())) {
//7.获取servlet-name元素
Element servletName = element.element("servlet-name");
//8.获取servlet-class元素
Element servletClass = element.element("servlet-class");
//9.getservlet文本打印
System.out.println(servletName.getText());
System.out.println(servletClass.getText());
}
}
} catch (DocumentException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
反射
由于程序已经运行,无法在其中进行new对象的建立,就无法使用对象。这是可以根据配置文件类全名去找对应的字节码文件,并加载进内存,并创建该类对象实例。这就需要使用反射技术完成。在运行状态中获取一个类(动态获取),并获取它的属性和方法,也可以调用这些属性和方法,使用反射可以在运行时对类,构造方法,普通方法和进行操作。
接口代码
package cn.aynortechnology.web.servlet;
public interface IMyServlet {
public void init();
public void service();
public void destory();
}
实现接口的类
package cn.aynortechnology.web.servlet;
public class MyServletImpl implements IMyServlet {
@Override
public void init() {
// TODO 自动生成的方法存根
System.out.println("1");
}
@Override
public void service() {
// TODO 自动生成的方法存根
System.out.println("2");
}
@Override
public void destory() {
// TODO 自动生成的方法存根
System.out.println("3");
}
}
模拟读取配置文件
package cn.aynortechnology.web.servlet;
import org.junit.Test;
public class TestMyServlet {
@Test
public void testMyServlet() {
MyServletImpl my = new MyServletImpl();
my.init();
my.service();
my.destory();
}
@Test
public void testMyServlet1() {
try {
//假设从配置文件中获取了这个类的全名
String className = "cn.aynortechnology.web.servlet.MyServletImpl";
Class clazz = Class.forName(className);
MyServletImpl my = (MyServletImpl)clazz.newInstance();
my.init();
my.service();
my.destory();
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
通过读取配置文件的方法来使反射完成对对象的调用
接口与上面相同
实现接口的类
package cn.aynortechnology.web.seevlet1;
public class MyServlet1 implements IMyServlet{
@Override
public void init() {
// TODO 自动生成的方法存根
System.out.println("Servlet1初始化完毕");
}
@Override
public void service() {
// TODO 自动生成的方法存根
System.out.println("Servlet1正在服务");
}
@Override
public void destory() {
// TODO 自动生成的方法存根
System.out.println("Servlet1已销毁");
}
}
重新编写web.xml文档
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app SYSTEM "web-app_2_3.dtd">
<web-app version="1.0">
<servlet>
<servlet-name>myServlet1</servlet-name>
<servlet-class>cn.aynortechnology.web.seevlet1.MyServlet1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myServlet1</servlet-name>
<url-pattern>/MyServlet1</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>myServlet2</servlet-name>
<servlet-class>cn.aynortechnology.web.seevlet1.MyServlet2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myServlet2</servlet-name>
<url-pattern>/MyServlet2</url-pattern>//这里必须有斜杠
</servlet-mapping>
</web-app>
XML文档使用的DTD约束如下
<?xml version="1.0" encoding="UTF-8"?>
<!--
模拟serblet2.3规范,如果开发人员需要在xml使用当前DTD约束,必须包括DOCTYPE。
格式如下:
<!DOCTYPE web-app SYSTEM "web-app_2_3.dtd">
-->
<!ELEMENT web-app (servlet*,servlet-mapping*,welcome-file-list?)>
<!ELEMENT servlet (servlet-name,description?,(servlet-class|jsp-file))>
<!ELEMENT servlet-mapping (servlet-name,url-pattern+)>
<!-- #PCDATA为只能出现文本 -->
<!ELEMENT servlet-name (#PCDATA)>
<!ELEMENT servlet-class (#PCDATA)>
<!ELEMENT url-pattern (#PCDATA)>
<!ELEMENT description (#PCDATA)>
<!ELEMENT jsp-file (#PCDATA)>
<!ELEMENT welcome-file-list (welcome-file+)>
<!ELEMENT welcome-file (#PCDATA)>
<!ATTLIST web-app version CDATA #IMPLIED>
测试,一整套流程
package cn.aynortechnology.web.seevlet1;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;
public class TestMyServlet {
@Test
public void testMyServlet() {
try {
//1.创建解析器对象
SAXReader saxReader = new SAXReader();
//2.通过解析器来加载web.xml文件,得到document对象
Document document = saxReader.read("src/cn/aynortechnology/web/seevlet1/web.xml");
//3.获取根元素节点
Element rootElement = document.getRootElement();
//4.根据元素名称获取子元素节点
Element servletelement = rootElement.element("servlet");
//5.根据元素名称获取servlet-class的文本节点
String servletClass = servletelement.element("servlet-class").getText();
System.out.println("已获取Class名称:"+servletClass);
//6.通过类全名获取字节码文件
Class clazz = Class.forName(servletClass);
//7.创建实例对象
MyServlet1 my = (MyServlet1) clazz.newInstance();
//8.调用实例对象里面的方法
my.init();
my.service();
my.destory();
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
使用JUnit测试运行,输出如下