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请求的区别和应用场景?