熟悉servlet,咱們不僅是要用到,還要完全研究他的繼承體系,若是以前沒有認真學習他的生命週期和運行過程,那麼繼承體系你也只能有個略懂。java
個人作法,本身寫類來模擬 genericservlet和httpservlet2個類!而且理解他們爲何要這麼作!設計模式
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); } }
至於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"); } }
時間急,請多指正!