今天,学习了XML的相关知识和反射。其实就是servlet的底层逻辑和运行步骤。为什么我们能通过配置web.xml来让servlet那样运行呢?今天其实就学习了这样的一个问题。
首先,是XML,XML和HTML相似,但不同的是XML可以自定义标签(比如html中规定了a标签就是超链接,但xml中没有任何规定) xml规定每个开始的标签必须有结束标签。比如<hello></hello>,且必须依次对应,如<b><i>hello</b></i>,这在html是可行的,但对于xml来说是不可行的,必须书写规范且准确。
之后,便是xml的书写规范,我们学习了两种规范——DTD约束和Schema约束,后者比前者要更加实用,但为了学习起见,先行学习了DTD约束。即通过DTD提供的框架进行XML文档的书写。而Schema约束也类似,也可通过提供好的框架进行书写,以下是代码:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app SYSTEM "web-app_2_3.dtd"> <web-app version="1.0"> <servlet> <servlet-name></servlet-name> <servlet-class></servlet-class> </servlet> <servlet-mapping> <servlet-name></servlet-name> <url-pattern></url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file></welcome-file> </welcome-file-list> </web-app>
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns="http://www.example.org/web-app_2_5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://www.example.org/web-app_2_5 web-app_2_5.xsd" 4 version="2.5"> 5 6 <servlet> 7 <servlet-name>helloServlet</servlet-name> 8 <servlet-class>xxxxxxxxxx</servlet-class> 9 </servlet> 10 <servlet-mapping> 11 <servlet-name>helloServlet</servlet-name> 12 <url-pattern>/hello</url-pattern> 13 </servlet-mapping> 14 </web-app>
其实际,我们发现XML文档无法被浏览器解析。那么我们如何解析XML文档的内容来被浏览器使用呢?我们可以使用dom4j解析。dom4j是一个解析器,通过这个解析器我们能够调用其中的API进行XML的解析。
以下是一个DEMO:
package cn.itheima.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/itheima/xml/schema/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"); System.out.println(servletName.getText()); System.out.println(servletClass.getText()); } } } catch (DocumentException e) { e.printStackTrace(); } } }
在学习完了XML的相关知识后,我们来学习Servlet的一个重要概念,反射。反射是指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。
使用反射,我们就可以在运行时对类,构造方法,普通方法等进行操作。
下面是代码演示:
1 package cn.itheima.web.servlet; 2 3 import org.junit.Test; 4 5 public class TestMyServlet { 6 7 @Test 8 public void testMyServlet(){ 9 MyServletImpl my = new MyServletImpl(); 10 my.init(); 11 my.service(); 12 my.destory(); 13 } 14 15 @Test 16 public void testMyServlet1(){ 17 try { 18 String className = "cn.itheima.web.servlet.MyServletImpl"; 19 Class clazz = Class.forName(className); 20 MyServletImpl my = (MyServletImpl) clazz.newInstance(); 21 my.init(); 22 my.service(); 23 my.destory(); 24 } catch (Exception e) { 25 e.printStackTrace(); 26 } 27 } 28 }
package cn.itheima.web.servlet; public interface IMyServlet { public void init(); public void service(); public void destory(); }
1 package cn.itheima.web.servlet; 2 3 public class MyServletImpl implements IMyServlet { 4 5 @Override 6 public void init() { 7 System.out.println("啊,俺来也……"); 8 } 9 10 @Override 11 public void service() { 12 System.out.println("我可以为你服务……"); 13 } 14 15 @Override 16 public void destory() { 17 System.out.println("啊,俺去也……"); 18 } 19 20 }
可以看到,这就是servlet的底层工作原理。