利用反射机制解析XMl
之前两篇文章我们学习了通过dom4j解析XML以及反射机制的简单应用
今天来看一个综合案例
今天看到一个面试题,通过反射机制,解析XML,实现servlet的服务
1.原理
当客户发起请求时,通过user.do去XML找到限定的类名,然后执行当中的方法。
没有用JavaWeb写,java项目道理都是一样的
整体思路
2.自定义一个接口 Servlet
package com.it.servlet;
public interface Servlet {
//服务多次
void services();
}
3.定义一个实现类 UserServlet
package com.it.servlet;
public class UserServlet implements Servlet {
@Override
public void services() {
System.out.println("--------------------user.do----------------------");
}
}
4.XMl文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>UserServlet</servlet-name>
<servlet-class>com.it.servlet.UserServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UserServlet</servlet-name>
<url-pattern>/user.do</url-pattern>
</servlet-mapping>
</web-app>
代码演示:
package com.it.XmlReflect;
import com.it.servlet.UserServlet;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.util.List;
//运用反射机制解析web.XML 调用servlet的方法
public class Foo {
//获取XMl资源路径 user.dir用户的当前工作目录
public static File XMLFile=new File(System.getProperty("user.dir") +"\\0911_reflect\\src\\web.xml");
//读取XML 获得document
public static Document getDocument(){
SAXReader saxReader=new SAXReader();
try {
return saxReader.read(XMLFile);
} catch (DocumentException e) {
e.printStackTrace();
}
return null;
}
//客户发起请求时 通过url(**.do) 比较 url-pattern 找到XML中的映射servlet-mapping
// 通过url-pattern-->servlet-name-->servlet-->servlet-name-->servlet-class(包名.类名);
public static String getServletName(String url){
//获取document
Document document=getDocument();
//获取根
Element root=document.getRootElement();
//获取所有元素
List<Element> elementList=root.elements("servlet-mapping");
for(Element element:elementList) {
if(element.element("url-pattern").getText().equals(url)){
//获取servlet的name
return element.element("servlet-name").getText();
}
}
return null;
}
//获取ClassName servlet-class
public static String getServletClass(String ServletName){
//获取document
Document document=getDocument();
//获取根
Element root=document.getRootElement();
List<Element> elementList=root.elements("servlet");
for(Element element:elementList) {
if(element.element("servlet-name").getText().equals(ServletName)){
//获取servlet的name
return element.element("servlet-class").getText();
}
}
return null;
}
public static void main(String[] args) {
String ServletClass=getServletClass(getServletName("/user.do"));
//com.it.servlet.UserServlet
try {
//创建一个servlet类
Class cls=Class.forName(ServletClass);
// UserServlet userServlet=new UserServlet();
//newInstance()返回object类型
UserServlet userServlet=(UserServlet) cls.newInstance();
//调用其中的方法 如dopost() doget()...
userServlet.services();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
}
在这里顺便了解了Class.forName的用法,以及它与new的区别,见下一篇文章,有详细介绍