servlet 详解(二)-继承体系

servlet 详解(二)-继承体系

熟悉servlet,咱们不仅是要用到,还要完全研究他的继承体系,若是以前没有认真学习他的生命周期和运行过程,那么继承体系你也只能有个略懂。java

个人作法,本身写类来模拟 genericservlet和httpservlet2个类!而且理解他们为何要这么作!设计模式

(一)模拟genericservlet

1,咱们新建一个类,如MyGenericServlet,让他实现Servlet、ServletConfig和Serializable网络

前2个类Servlet、ServletConfig,咱们不须要详述,前面我已经讲过做用,Serializable这个接口是为了让他能在网络上传输。ide

2,实现他的一些基本方法,以下:post

private ServletConfig config;//实现config参数

@Override
public void destroy() {
    // TODO Auto-generated method stub
    
}

@Override
public String getInitParameter(String param) {
    // TODO Auto-generated method stub
    return config.getInitParameter(param);
}

@Override
public Enumeration<String> getInitParameterNames() {
    // TODO Auto-generated method stub
    return config.getInitParameterNames();
}

@Override
public String getServletName() {
    // TODO Auto-generated method stub
    return null;
}

@Override
public ServletConfig getServletConfig() {
    // TODO Auto-generated method stub
    return this.config;
}

@Override
public String getServletInfo() {
    // TODO Auto-generated method stub
    return null;
}

@Override
public void init(ServletConfig config) throws ServletException {
    // TODO Auto-generated method stub
    this.config=config;
    init();
    
}
public void init() throws ServletException {

    
}

@Override
public void service(ServletRequest arg0, ServletResponse arg1)
        throws ServletException, IOException {
    // TODO Auto-generated method stub
    
    System.out.println("hello world");
    
    
}

public ServletContext getServletContext(){
    return config.getServletContext();
}

咱们说servlet的生命周期是首先运行带有参的init方法,那么咱们想要子类重写而且保障config被传入就必定要定义一个空参的方法,而且在有参方法中执行,这样根据多态的特性,子类重写父类init方法,被执行的是子类的方法,因此咱们只须要在子类重写空参方法,这样保障config被传入后再执行本身的方法,若是子类重写有参方法,那么悲哀了,确定报错,就没有ServerletConfig对象了!因此在这个类中的init方法是这么实现的!学习

@Override
public void init(ServletConfig config) throws ServletException {
    // TODO Auto-generated method stub
    this.config=config;
    init();
    
}
public void init() throws ServletException {

    
}

而后讲一下为何要用getInitParameter(String param)这个方法,子类想要获取config对象,若是没有这个方法咱们确定是这么调用!优化

super.getServletConfig().getInitParameter("param");

从中看出,servlet为了优化一点点细节,从得多好,他用了一个getInitParameter(String param)方法,让子类能够少写一点点代码.this

super.getInitParameter("param");

而自身只多写了这样一个方法,因此咱们父类的构造要合理设计!设计

public String getInitParameter(String param) {
        // TODO Auto-generated method stub
        return config.getInitParameter(param);
    }

子类只须要这样写:code

package gwd.com.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class Server2 extends MygenericServlet {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Override
    public void init() throws ServletException {
        // TODO Auto-generated method stub
        System.out.println("这是我自定义的初始化");
    }

    @Override
    public void service(ServletRequest arg0, ServletResponse arg1)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        String code=getInitParam("code");
        System.out.println(code);
    }
    
    

}

(二)模拟HttpServlet

至于HttpServerlet这个类是为了http协议而生的,咱们建一个MyHttpServlet类!他只处理http请求!而响应或请求咱们都在service中实现!

咱们再来看看上面这个类(Servlet2)中的service方法!

public void service(ServletRequest arg0, ServletResponse arg1)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        String code=getInitParam("code");
        System.out.println(code);
    }

咱们看到他的参数名ServletRequest arg0, ServletResponse arg1!ServletRequest和ServletResponse只能用到普通请求,要实现http必须依靠HttpServletRequest和HttpServletResponse来实现,因此咱们要把这两个参数强转,而后重载一个service方法单独处理,固然为了代码复用,咱们这个MyHttpServlet必须继承MyGenericServlet,代码以下:

package gwd.com.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyHttpServlet extends MygenericServlet {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Override
    public void service(ServletRequest request, ServletResponse response)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        HttpServletRequest res=(HttpServletRequest) request;
        HttpServletResponse resp=(HttpServletResponse)response;
        service(res, resp);
    }

    private void service(HttpServletRequest res, HttpServletResponse res2) {
        // TODO Auto-generated method stub
        String method=res.getMethod();
        //System.out.println(method);
        if("GET".equals(method)){
            doGet(res,res2);
        }
        else if("POST".equals(method)){
            doPost(res,res2);
        }
        
    }

    protected void doPost(HttpServletRequest res, HttpServletResponse res2) {
        // TODO Auto-generated method stub
        
    }

    protected void doGet(HttpServletRequest res, HttpServletResponse res2) {
        // TODO Auto-generated method stub
        
    }
    

}

在重载的service中,咱们能够判断出请求的是什么方法,是get仍是post,而后分离出来处理,给子类自由实现,这就是著名的模板方法设计模式!(后面我再单独写博!),注意了若是这2个方法写成private的活,子类将没法重写!

而后子类只要继承并重写dopost和doget方法就能够了,咱们之后写servlet也只须要继承httpservlet方法,查看httpservlet和GeneticServerlet类的源码,是否是和个人设计差很少呢?

子类咱们能够这么写,是否是愈来愈简单了呢?

package gwd.com.servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class Sever1 extends MyHttpServlet{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest req,HttpServletResponse resp){
        
        System.out.println("doget");
        
    }
    
    protected void doPost(HttpServletRequest req,HttpServletResponse resp){
        
        System.out.println("dopost");
        
    }
    
    

}

(三)咱们弄张图来总结一下继承体系!

时间急,请多指正!

相关文章
相关标签/搜索