到这里任务似乎已经完了,但是大家感兴趣的还没有说,就是代码层面了。这里大致的说说。
再回到前面那个Servlet代码,会发现几个特点,第一它一定要继承HttpServlet类,第二,我们一般只需要写好doGet和doPost里面的代码。第三,init方法是什么意思。这几个特点不搞清楚,那么又迷茫了。
问题呢,还是回到了Servlet了。呵呵,先解决简单的,应该已经知道,一般某个Servlet之后被实例化一次,在这次实例化的时候呢,就会先调用init方法,之后就再也不调用了。所以里面可以放一些什么代码就应该清楚了,比如初始化的参数等。只不过一般都不怎么写这个方法,都是让它默认的调用超类的初始化方法。super.init();这行代码可不简单啊,你可以结合继承来想想,当然放到c++里面去想更好,因为c++是力挺继承多态的呢。
那前面两个问题呢?那就要问问容器和看看这个类的class文件了。从头讲吧,如果你看的书比较旧的话,应该都是说Servlet是继承GenericServlet类,它才是Servlet的鼻祖哦。看看几个核心类的结构吧
public abstract class GenericServlet implements Servlet, ServletConfig, Serializable
public abstract class HttpServlet extends GenericServlet implements Serializable
剔除Serialzable接口和 ServletConfig接口,剩下的结构是:
public abstract class GenericServlet implements Servlet
public abstract class HttpServlet extends GenericServlet
这样就简单了,再看看Servlet接口:
public abstract interface Servlet {
// Methods
void init(ServletConfig servletConfig) throws ServletException;
ServletConfig getServletConfig();
void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException;
String getServletInfo();
void destroy();
}
剔除其他方法,就剩下一个关键的方法了service,这个方法可以算是核心的方法了。是它最先拿到请求的。(这里的请求已经是封装成一个ServletRequest对象了)
然后再跟踪下这个方法,在GenericServlet类中是这样子的:
public abstract void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException;
抽象的哦,也是不搞事的,再看看HttpServlet类中的:
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { }
同时这个类包含了doGet、doHead、doPost、doPut、doDelete、doOptions、doTrace等方法。
然后再来过一遍吧,ServletRequest一过来,就找service方法,可是你的类里面没有这个方法,于是找它的超类的方法,正好在HttpServlet中找到,(如果还是没有,就继续往上找,这个可以关注多态的知识和java类的类型数据的方法表的知识)然后就调用,由于我们的Http请求一般只是Post或Get,于是这个service方法会判断到底是调用doGet还是doPost,会进行相应的调用,如果你不熟悉多态和java类的方法表又会晕了,HttpServlet中的service方法怎么可以调到它的子类的方法呢?因为这个service方法还是你的Servlet的方法,只是你没有重载而已。java类的方法表真的很赞。于是同样就调用了你的类的doGet或doPost方法了。