Generic-汉语意思:类的adj
GenericServlet是一个抽象类,它的源码很容易看懂,继承Servlet接口和ServletConfig接口
所有它里面有父接口里面的方法,所以它就是在Servlet的基础上把一些功能给封装起来了(省的我们手写了)。把ServletConfig给保存下来,以便使用它可以获得其他值。
它里面有这些方法(部分)
void destroy()
String getInitParameter(string name)
Enumeration getInitParameterNames()
ServletConfig getServletConfig()
ServletContext getServletContext()
...
模拟GenericServlet抽象类
1 package one.servlet; 2 3 import java.io.IOException; 4 5 import javax.servlet.Servlet; 6 import javax.servlet.ServletConfig; 7 import javax.servlet.ServletContext; 8 import javax.servlet.ServletException; 9 import javax.servlet.ServletRequest; 10 import javax.servlet.ServletResponse; 11 12 //模拟GenericServlet类 13 public class BServlet implements Servlet{ 14 private ServletConfig config;//一个成员 15 16 @Override 17 public void destroy() { 18 System.out.println("啊,我要死了!"); 19 } 20 //这个方法一定会在init()方法之后被调用! 21 //init()被调用后,本类的成员this.config已经有值了! 22 @Override 23 public ServletConfig getServletConfig() { 24 return this.config; 25 } 26 //没有用的东西 27 @Override 28 public String getServletInfo() { 29 return "用字符串简单描述Servlet"; 30 } 31 /* 32 * 由Tomcat来调用,并且调用一次 33 * 它是这些方法中第一个被调用的,它会在构造器之后马上被调用(先创建对象,再调用方法)! 34 * */ 35 @Override 36 public void init(ServletConfig config) throws ServletException { 37 //把Tomcat传递的ServletConfig赋值给本类的一个成员,其实就是把它保存起来,方便在其他地方用 38 this.config=config; 39 } 40 41 @Override 42 public void service(ServletRequest req, ServletResponse res) 43 throws ServletException, IOException { 44 System.out.println("每次处理请求都会被调用!"); 45 } 46 47 public ServletContext getServletContext(){ 48 return config.getServletContext(); 49 } 50 51 public String getInitParameter(String name){ 52 return config.getInitParameter(name); 53 } 54 //等等方法都可以模拟GenericServlet里的方法 55 }
其他Servlet可以继承上述的模拟GenericServlet(也就是继承BServlet),但是如果重写init()方法,就会覆盖父类中的this.config=config;然后该类中的部分其他方法将不能使用。
解决方案:
父类BServlet
1 @Override 2 public void init(ServletConfig config) throws ServletException { 3 //把Tomcat传递的ServletConfig赋值给本类的一个成员,其实就是把它保存起来,方便在其他地方用 4 this.config=config; 5 init(); 6 } 7 //本类定义的方法,不是Servlet接口中的方法。 8 public void init(){ 9 10 }
子类CServlet
1 package one.servlet; 2 3 public class CServlet extends BServlet{ 4 5 //服务器不会调用这个方法,但是会调用父类有参的init方法,然后再去掉用父类的init无参的方法 6 @Override 7 public void init() { 8 System.out.println("子类的CServlet重载之后的方法"); 9 } 10 }
从而在请求CServlet的时候,就会执行重写过后init方法中的代码。
也就是子类继承了父类有参的init()方法,服务器调用有参的之后,然后再去调用init();这个调用
总结:解决了数据库所给的config的保存问题,以及子类重写init()方法后的问题。这就是GenericServlet的原理。
使用GenericServlet
DServlet.java
1 package one.servlet; 2 3 import java.io.IOException; 4 5 import javax.servlet.GenericServlet; 6 import javax.servlet.ServletException; 7 import javax.servlet.ServletRequest; 8 import javax.servlet.ServletResponse; 9 10 public class DServlet extends GenericServlet { 11 //要想在出生时笑一笑,覆盖无参的init() 12 13 @Override 14 public void init() throws ServletException { 15 System.out.println("哈哈,我出生了!"); 16 } 17 18 @Override 19 public void service(ServletRequest arg0, ServletResponse arg1) 20 throws ServletException, IOException { 21 System.out.println("hello world!"); 22 } 23 24 //死的時候留遺言 25 @Override 26 public void destroy() { 27 System.out.println("我走了"); 28 } 29 }
web.xml配置
//部分配置 <servlet> <servlet-name>xx</servlet-name> <servlet-class>one.servlet.DServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>xx</servlet-name> <url-pattern>/DServlet</url-pattern> </servlet-mapping>
请求DServlet--http://localhost:8080/XJS_Servlet1/DServlet
哈哈,我出生了! hello world!