Java培訓(xùn)之GenericServlet類(lèi)(二)
更新時(shí)間:2017-05-31 來(lái)源:黑馬程序員Java培訓(xùn)學(xué)院 瀏覽量:
由例1-1可知,當(dāng)前的MyServlet類(lèi)中不僅包含了Servlet接口的五個(gè)方法,還包含了以下方法:
public ServletConfig getServletContext()public String getInitParameter(String name)public String getServletName()由于GenericServlet類(lèi)實(shí)現(xiàn)了ServletConfig接口,那么必然重寫(xiě)了ServletConfig的方法,因此在MyServlet 類(lèi)中也要定義了ServletConfig的相關(guān)方法,這些方法的實(shí)現(xiàn)都是通過(guò)成員變量config調(diào)用自身的方法來(lái)實(shí)現(xiàn)的。
另外MyServlet類(lèi)中還有一個(gè)無(wú)參的init()方法,該方法不是生命周期方法,它會(huì)被生命周期方法init(ServletConfig)方法調(diào)用。 這樣做的目的是為了方便繼承MyServlet類(lèi)的子類(lèi),完成自己所需要的初始化工作,而不用再定義一個(gè)ServletConfig類(lèi)型的成員變量。
(2)再創(chuàng)建一個(gè)Servlet類(lèi),讓該類(lèi)繼承MyServlet 類(lèi),具體代碼如例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中定義了本類(lèi)的init(ServletConfig)方法,該方法會(huì)覆蓋父類(lèi)的init(ServletConfig)方法。那么第一次訪問(wèn)該Servlet時(shí),服務(wù)器會(huì)調(diào)用子類(lèi)的init()生命周期方法進(jìn)行初始化,父類(lèi)的init()生命周期方法沒(méi)有被調(diào)用,那么父類(lèi)的config成員就為null,當(dāng) SonServlet 類(lèi)中的service方法調(diào)用父類(lèi)的getInitParameter()方法時(shí)就會(huì)出現(xiàn)空指針異常。所以,SonServlet 類(lèi)中不能覆寫(xiě)有參的init()方法,而應(yīng)該覆寫(xiě)無(wú)參的init()方法。這也是為什么在MyServlet類(lèi)中定義一個(gè)無(wú)參的init()方法,然后再在有參的init方法中調(diào)用無(wú)參的init方法的原因。
以上案例就是為了方便開(kāi)發(fā)人員開(kāi)發(fā)Servlet,以后就不用去實(shí)現(xiàn)Servlet接口。現(xiàn)在我們來(lái)看一下GenericServlet的源碼,源碼的jar包點(diǎn)擊此處 進(jìn)行下載。具體代碼如例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類(lèi)的原理和我們剛才寫(xiě)的MyServlet 類(lèi)的原理是一樣的。繼承GenericServlet 類(lèi)比實(shí)現(xiàn)Servlet接口更加方便Servlet開(kāi)發(fā)。
本文版權(quán)歸黑馬程序員Java培訓(xùn)學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明作者出處。謝謝!
作者:黑馬程序員Java培訓(xùn)學(xué)院
首發(fā):http://javaee.itheima.com/