如果大家用过tomcat可以看一下在<tomcat安装目录>/Webapps/examples/Web-INF/Web.xml文件中有这样一段
<servlet-mapping>
<servlet-name>invoker</servlet-name>
<url-pattern>/servlet/*</url-pattern>
</servlet-mapping>
而在<tomcat安装目录>/conf/Web.xml文件中,还有一段
<servlet>
<servlet-name>invoker</servlet-name>
<servlet-class>
org.apache.catalina.servlets.InvokerServlet
</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
这样配置,就把所有/servlet/*格式的url发送给InvokerServlet.下一步InvokerServlet就会把/servlet/*中的*部分当作某个servlet的类名去调用.比如url是
/servlet/HelloWorld.那么InvokerServlet就会去实例化HelloWorld,并调用它的service方法.这样就不用把web应用程序中用到的每个servlet都写到Web-
INF.xml中了.所以InvokerServlet又叫servlet激发器
我也写了一个Invoker来接收xmlhttp发出的请求,不过我的Invoker是去读ServletMapping.xml文件,并根据url在该XML文件中取得类名className和方法名
methodName.然后实例化该类,并调用它相应的方法.
1 解析XML配置文件
public class Invoker extends HttpServlet{
Document doc = null;
//覆盖init()方法在Invoker实例化时即解析XML文件
public void init(ServletConfig config)throws ServletException{
super.init(config);
InputSource ips = config.getServletContext().getResourceAsStream(
"/Web-INFO/ServletMapping.xml");
doc = parseXmlFile(xmlFileUrl,false);
}
public Document parseXmlFile(InputSource ips,boolean validating)
throws SAXException,ParserConfigurationException,IOException{
try{
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder parser = dbf.newDocumentBuilder();
doc = parser.parse(ips);
return doc;
} catch (SAXException e) {
} catch (ParserConfigurationException e) {
} catch (IOException e) {
}
return null;
}
}
上面的代码很简单,因为在Web.xml中的<load-on-startup>.所以Invoker在服务器启动时就加载,并调用init方法去解析ServletMapping.xml.解析完成后返回
doc,剩下的事就好办了.现在要说的是,最初的代码不是这样的,是如下:
public void init(ServletConfig config)throws ServletException{
super.init(config);
URL xmlFileUrl = config.getServletContext().getResource("/Web-INFO/ServletMapping.xml");
File file = xmlFileUrl.getFile();
doc = parseXmlFile(file,false);
}
public static Document parseXmlFile(File file, boolean validating) {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(validating);
Document doc = factory.newDocumentBuilder().parse(file);
return doc;
} catch (SAXException e) {
} catch (ParserConfigurationException e) {
} catch (IOException e) {
}
return null;
}
上面的代码先取得URL,再用getFile方法得到文件后再解析文件.我在本机直接部署文件夹,测试通过.但过我传到测试服务器然后打成ear包部署的时候竟然报错
了,faint!!
URL xmlFileUrl = config.getServletContext().getResource("/Web-INFO/ServletMapping.xml");
这句取到的xmlFileUrl 竟然是null.然后我又用getRealPath.并把参数换成("/")来取根目录,得到的都是null.上网一查才知道,如果用ear/war包来部署,就不
能用getRealPath或getResource来取得路径.昏,这是什么规矩啊.后来又查半天,才找到直接解析流这个方法.
2 根据URL调用相应的方法
先看一下servletMapping.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE map [ <!ELEMENT map (serlet_mapping*) >
<!ELEMENT serlet_mapping EMPTY >
<!ATTLIST serlet_mapping url ID #REQUIRED
class_name CDATA #REQUIRED>
method_name CDATA #REQUIRED ]>
<map>
<serlet_mapping url="classname.methodname.servlet"
class_name="classname"
method_name="methodname"/>
</map>
下面覆盖了Invoker的service方法
public void service(HttpServletRequest request,
HttpServletResponse response)throws ServletException,IOException{
try{
//得到发送请求的URI,对于http://localhost:8001/classname.methodname.servlet
//getRequestURI将返回"/classname.methodname.servlet"
String requestUri = request.getRequestURI().replaceAll("/","");
element = doc.getElementById(requestUri);//根据URL,取得XML中的元素.
String className = element.getAttribute("class_name");
String methodName = element.getAttribute("method_name");
Class class = Class.forName(className);//加载类
Method method = class.getDeclaredMethod(methodName, new Class[]{HttpServletRequest.class,
HttpServletResponse.class});//根据方法名取得方法
Object obj = class.newInstance();//实例化类
method.invoke(obj, new Object[] {request,response});//调用方法
}catch(Exception e){}
}
到这里,Invoker激发器就完成了,剩下的事就交给所调用的方法去完成,查出数据,再写回.
导出工作总结完毕!