1. 程式人生 > >讀書筆記《看透 Spring MVC》6. Servlet

讀書筆記《看透 Spring MVC》6. Servlet

Servlet是一套規範。

Servlet 結構圖:

1. Servlet介面

public void init(ServletConfig config) throws ServletException; 

 ServletConfig引數由容器傳入,當load-on-startup設定為負數或者不設定時會在Servlet第一次用到才被呼叫,只會呼叫一次。
 ServletConfig中儲存了Servlet xml配置檔案的init-param標籤的配置,例如Spring MVC中的配置:

<!-- MVC Servlet -->
    <servlet>
        <servlet-name>springServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath*:/spring-mvc*.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

 

public ServletConfig getServletConfig();
public void service(ServletRequest req, ServletResponse res)throws ServletException, IOException;

用於處理一個請求
 

public String getServletInfo();

獲取一些Servlet相關的資訊,例如版權、作者等,需要自己實現。
 

public void destroy();

Servlet銷燬,一般指關閉伺服器,釋放一些資源,會回撥用一次。
 

 2. ServletConfig介面

   public String getServletName();
   public ServletContext getServletContext();
   public String getInitParameter(String name);
   public Enumeration getInitParameterNames();

getServletContext代表應用本身,ServletContext裡面的引數被整個應用共享

ServletConfig是Servlet級的;

ServletConfig是Context(Application)級的。

Tomcat的Host級操作(日後再做了解)。


ServletConfig和ServletContext最常見的使用之一是傳遞初始化引數,即:getInitParameter方法。

ServletContext中非常常用的方法就是儲存Application級的屬性,即:setAttribute方法。

注:getInitParameter與setAttribute是兩套資料,不會同名覆蓋。

3. GenericServlet

  • 實現了ServletConfig介面,可以直接呼叫ServletConfig中的方法。
  • 提供了無參的init方法(模板方法,供子類實現)。
  • 提供了log方法,一個記錄日誌,一個記錄異常。不常用。
  • 實現了Servlet的service方法(空的,啥也沒寫,不知道有啥用)。
  public void init(ServletConfig config) throws ServletException {
	this.config = config;
	this.init();
    }
  
  public void init() throws ServletException {    }  
  
  public abstract void service(ServletRequest req, ServletResponse res)
	throws ServletException, IOException;
    

4. HttpServlet

主要的工作是處理請求(serivce方法)

  • 首先將ServletRequest、ServletResponse轉換為HttpServletRequest、HttpServletResponse。
  • 然後將不同的請求路由到不同的處理方法中,Spring MVC中是將所有請求合併到一個方法中處理。
  public void service(ServletRequest req, ServletResponse res)
	throws ServletException, IOException
    {
	HttpServletRequest	request;
	HttpServletResponse	response;
	
	try {
	    request = (HttpServletRequest) req;
	    response = (HttpServletResponse) res;
	} catch (ClassCastException e) {
	    throw new ServletException("non-HTTP request or response");
	}
	service(request, response);
    }

  protected void service(HttpServletRequest req, HttpServletResponse resp)
	throws ServletException, IOException
    {
	String method = req.getMethod();

	if (method.equals(METHOD_GET)) {
	    long lastModified = getLastModified(req);
	    if (lastModified == -1) { 
		doGet(req, resp);
	    } else {
		long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
		if (ifModifiedSince < (lastModified / 1000 * 1000)) { 
		    maybeSetLastModified(resp, lastModified);
		    doGet(req, resp);
		} else {
		    resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
		}
	    }

	} else if (method.equals(METHOD_HEAD)) {
	    long lastModified = getLastModified(req);
	    maybeSetLastModified(resp, lastModified);
	    doHead(req, resp);

	} else if (method.equals(METHOD_POST)) {
	    doPost(req, resp);
	    
	} else if (method.equals(METHOD_PUT)) {
	    doPut(req, resp);	
	    
	} else if (method.equals(METHOD_DELETE)) {
	    doDelete(req, resp);
	    
	} else if (method.equals(METHOD_OPTIONS)) {
	    doOptions(req,resp);
	    
	} else if (method.equals(METHOD_TRACE)) {
	    doTrace(req,resp);
	    
	} else { 
	    String errMsg = lStrings.getString("http.method_not_implemented");
	    Object[] errArgs = new Object[1];
	    errArgs[0] = method;
	    errMsg = MessageFormat.format(errMsg, errArgs);
	    
	    resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
	}
    }
    

請求型別:GET、POST、PUT、HEAD、DELETE、OPTIONS、TRACE。

 

遺留問題:

  • Tomcat中Servlet的init方法的呼叫過程?
  • GET與POST請求的區別和應用場景?