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");
        
    }
    
    

}

(三)咱們弄張圖來總結一下繼承體系!

時間急,請多指正!

相關文章
相關標籤/搜索