讀書筆記《看透 Spring MVC》6. Servlet
阿新 • • 發佈:2018-12-10
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請求的區別和應用場景?