1. 程式人生 > >getServletContext()空指標異常的原因 和 Servlet的init方法

getServletContext()空指標異常的原因 和 Servlet的init方法

問題:
寫servlet時當在doGet/doPost方法中要獲取ServletContext物件時,(比如:
ServletContext context=getServletContext();
out.print(context.getServerInfo());
)時而會出現下面的異常提示,有時可以有時又不行,找了半天問題總不得要領。
java.lang.NullPointerException
javax.servlet.GenericServlet.getServletContext(GenericServlet.java:159)
servletdemo.FirstServlet.process(FirstServlet.java:51)


原來我重寫了init(ServletConfig),但第一行沒有呼叫super.init(config);就是這導致了錯誤!父類的init(ServletConfig)有處理獲取ServletContext物件的引用,在doGet()等方法中才能夠通過getServletContext()方法獲取到SeverletContext物件!!
public void init(ServletConfig config) throws ServletException{
super.init(config);
。。。。
}

//-------------------------------------------------------------------------------------------------------------

 init方法是在Servlet例項化之後執行的,並且只執行一次。
.先說init(ServletConfig)中引數ServletConfig,代表的是配置資訊。即在web.xml中配置的資訊,比如:

    <servlet>         <servlet-name>RDSDispatchServlet</servlet-name> <display-name>RDSDispatchServlet</display-name>         <servlet-class>flex.rds.server.servlet.FrontEndServlet</servlet-class> <init-param> <param-name>useAppserverSecurity</param-name> <param-value>true</param-value> </init-param>                 <load-on-startup>10</load-on-startup>     </servlet>    在程式中可以用this.getServletConfig()方法得到ServletConfig的例項,然後用ServletConfig的相應方法 可以得到ServletConfig的名字(getServletName)和配置引數的名字(getInitParameter("name"))或者 名字列舉(getInitParameterNames()),並且通過引數名字得到相應的引數值。具體方法參見API。


二.再說說init方法,從原始碼中我們不難發現:Servlet接口裡面只有init(ServletConfig),這是供tomcat呼叫的。GenericServlet類裡面有成員變數ServletConfig,init(ServletConfig)方法和init()方法:

                        private transient ServletConfig config;

                        public void init(ServletConfig config) throws ServletException{
                            this.config=config;
                            this.init();
                        }

                        public void init() throws ServletException{

                        }
現在一切都很明瞭了,當容器(tomcat)幫忙呼叫init(ServletConfig config)並且給傳過來一個引數config,這個方法把引數物件的引用指向類的成員變數this.config,並且呼叫類的 this.init()方法。如果我們在寫Servlet類時只要重寫init(ServletConfig config)就可以了,但是init()不就成了多餘的了嗎?實際上init()方法是為了防止程式設計師在寫Servlet類重寫 init(ServletConfig config)時忘記寫super.init(ServletConfig config),這樣就容易造成出現空指標異常。而這就要求我們最好不要重寫init(ServletConfig config)。