全国咨询/投诉热线:400-618-4000

Java培训之GenericServlet类

更新时间:2016年07月25日17时52分 来源:传智播客Java培训学院 浏览次数:

1.GenericServlet原理分析

GenericServlet类是一个抽象类,并且是Servlet接口的实现类,HttpServlet类的父类,下面我们通过一张图来更直观的了解GenericServlet的类结构,如图1-1所示:

                                                           图1-1 GenericServlet类结构                                          
通过图1-1发现,GenericServlet类不仅实现了Servlet接口,还实现了ServletConfig接口。因此,在GenericServlet类中一定包含Servlet接口和ServletConfig接口的所有方法.。接下来,我们创建一个类来模拟GenericServlet的功能,详情请参考GenericServlet案例详解,点击此处 下载源代码。
(1)创建应用Example11,新建一个类MyServlet,该类实现了Servlet接口,具体代码如例1-1所示:
例1-1 MyServlet.java
public class MyServlet implements Servlet {
    /*
     * 成员变量config
     * */
     private ServletConfig config;
     public void init(){}
    @Override
    public void destroy() {
       System.out.println("destroy run......");
    }
    /*
     *  返回config,该方法一定在init方法之后执行
     * */
    @Override
    public ServletConfig getServletConfig() {
       return config;
    }
    @Override
    public String getServletInfo() {
       return "MyServlet....";
    }
/*
 * init()方法是这些方法中,最先被调用的,在本类构造方法执行后执行.
 * */
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        /*
         * 将服务器创建的servletConfig对象赋值给本类的成员变量config,方便在其他方法中使用
         * */
       this.config=servletConfig;
           init();
    }
    @Override
    public void service(ServletRequest arg0, ServletResponse arg1)
           throws ServletException, IOException {
       System.out.println("service run ......");     
    }
    /*
     * 获得Servlet的初始化参数
     * */
    public String getInitParameter(String name){
       return this.config.getInitParameter(name);
    }
    /*
     * 获得ServletContext对象
     * */
    public ServletContext getServletContext(){
       return this.config.getServletContext();
    }
    public String getServletName(){
       return this.config.getServletName();
    }
}
由例1-1可知,当前的MyServlet类中不仅包含了Servlet接口的五个方法,还包含了以下方法:
  • public ServletConfig getServletContext()
  • public String getInitParameter(String name)
  • public String getServletName()
由于GenericServlet类实现了ServletConfig接口,那么必然重写了ServletConfig的方法,因此在MyServlet 类中也要定义了ServletConfig的相关方法,这些方法的实现都是通过成员变量config调用自身的方法来实现的。
另外MyServlet类中还有一个无参的init()方法,该方法不是生命周期方法,它会被生命周期方法init(ServletConfig)方法调用。 这样做的目的是为了方便继承MyServlet类的子类,完成自己所需要的初始化工作,而不用再定义一个ServletConfig类型的成员变量。
(2)再创建一个Servlet类,让该类继承MyServlet 类,具体代码如例1-2所示:
例1-2  SonServlet.java
public class SonServlet extends MyServlet{
    @Override
    public void init(ServletConfig config) {
       // TODO Auto-generated method stub
       System.out.println("i am sonservlet.......");
    }
    @Override
    public void service(ServletRequest arg0, ServletResponse arg1)
           throws ServletException, IOException {
       String value=getInitParameter("name");
    }
}
由例1-2可知,在SonServlet中定义了本类的init(ServletConfig)方法,该方法会覆盖父类的init(ServletConfig)方法。那么第一次访问该Servlet时,服务器会调用子类的init()生命周期方法进行初始化,父类的init()生命周期方法没有被调用,那么父类的config成员就为null,当 SonServlet 类中的service方法调用父类的getInitParameter()方法时就会出现空指针异常。所以,SonServlet 类中不能覆写有参的init()方法,而应该覆写无参的init()方法。这也是为什么在MyServlet类中定义一个无参的init()方法,然后再在有参的init方法中调用无参的init方法的原因。
以上案例就是为了方便开发人员开发Servlet,以后就不用去实现Servlet接口。现在我们来看一下GenericServlet的源码,源码的jar包点击此处 进行下载。具体代码如例1-3所示:
例1-3 GenericServlet.java
public abstract class GenericServlet implements Servlet, ServletConfig,
        java.io.Serializable {
    private static final long serialVersionUID = 1L;
    private transient ServletConfig config;
    public GenericServlet() {}
    @Override
    public void destroy() {}
    @Override
    public String getInitParameter(String name) {
        return getServletConfig().getInitParameter(name);
    }
    @Override
    public Enumeration<String> getInitParameterNames() {
        return getServletConfig().getInitParameterNames();
    }
    @Override
    public ServletConfig getServletConfig() {
        return config;
    }
    @Override
    public ServletContext getServletContext() {
        return getServletConfig().getServletContext();
    }
    @Override
    public String getServletInfo() {
        return "";
    }
    @Override
    public void init (ServletConfig config) throws ServletException {
        this.config = config;
        this.init();
    }
    public void init() throws ServletException {}
    public void log(String msg) {
        getServletContext().log(getServletName() + ": " + msg);
    }
    public void log(String message, Throwable t) {
        getServletContext().log(getServletName() + ": " + message, t);
    }
    @Override
    public abstract void service(ServletRequest req, ServletResponse res)
            throws ServletException, IOException;
    @Override
    public String getServletName() {
        return config.getServletName();
    }
}
由例1-3可知,GenericServlet类的原理和我们刚才写的MyServlet 类的原理是一样的。继承GenericServlet 类比实现Servlet接口更加方便Servlet开发。

本文版权归传智播客Java培训学院所有,欢迎转载,转载请注明作者出处。谢谢!
作者:传智播客Java培训学院
首发:http://www.itcast.cn/javaee

javaee

python

web

ui

cloud

test

c

netmarket

pm

Linux

movies

robot

uids

北京校区

    14天免费试学

    基础班入门课程限时免费

    申请试学名额

    15天免费试学

    基础班入门课程限时免费

    申请试学名额

    15天免费试学

    基础班入门课程限时免费

    申请试学名额

    15天免费试学

    基础班入门课程限时免费

    申请试学名额

    20天免费试学

    基础班入门课程限时免费

    申请试学名额

    8天免费试学

    基础班入门课程限时免费

    申请试学名额

    20天免费试学

    基础班入门课程限时免费

    申请试学名额

    5天免费试学

    基础班入门课程限时免费

    申请试学名额

    0天免费试学

    基础班入门课程限时免费

    申请试学名额

    12天免费试学

    基础班入门课程限时免费

    申请试学名额

    5天免费试学

    基础班入门课程限时免费

    申请试学名额

    5天免费试学

    基础班入门课程限时免费

    申请试学名额

    10天免费试学

    基础班入门课程限时免费

    申请试学名额