一、Servlet
Spring MVC中核心Servlet(DispatcherServlet)的继承结构 图标(C)表示是类,而图标(I)表示接口

而上图的其中HttpServlet、GenericServlet、Servlet、ServletConfig 都在 javax-servlet-api-x.x.x.jar里面(x.x..x表示版本(如4.0.0))
而其他的类或接口都在 spring-xx.jar里面
1、Servlet
Servlet3.1的Servlet的接口代码如下:
package javax.servlet;
import java.io.IOException;
public interface Servlet {
public void init(ServletConfig config) throws ServletException;
public ServletConfig getServletConfig();
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException;
public String getServletInfo();
public void destroy();
}
init方法在容器启动时被容器调用(当load-on-startup设置为负数或者不设置时会在Servlet第一次用到时才被调用),
service方法用于具体处理一个请求;
getServiceInfo方法可以获取一些Servlet相关的信息,如作者,版权等,可以自定义实现,默认返回空字符串。
destroy方法 销毁Servlet,只会调用一次。
init方法被调用时传入ServletConfig类型参数。
web.xml配置Spring MVC Servlet:
<!-- Spring MVC Servlet -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring/spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
init-param标签配置参数通过ServletConfig来保持的。
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:/applicationContext.xml
</param-value>
</context-param>
context-param配置的contextConfigLocation配置到了ServletContext中。
在servlet中获取相对应的值:
String contextLocation = getServletConfig().getServletContext().getInitParameter("contextConfigLocation");
String servletLocation = getServletConfig().getInitParameter("contextConfigLocation");
定义Spring MVC的Servlet时制定文件位置的contextConfigLocation参数就保存在ServletConfig中。
Servlet通过文件xml配置,解使xml时会把配置项设置到StandardWrapper中。


StandardWrapper继承了ServletConfig接口,代码如下:
package javax.servlet;
import java.util.Enumeration;
public interface ServletConfig {
public String getServletName();
public ServletContext getServletContext();
public String getInitParameter(String name);
public Enumeration<String> getInitParameterNames();
}
1、-->StandardWrapper类调用initServlet方法
-->GenericServlet类(Servlet)调用init方法
-->HttpServletBean类调用init()方法
而StandardWrapper类在Tomcat中,StandardWrapper类是Tomcat中的Wrapper接口的实现类,而Wrapper是Container容器的子容器之一。每一个Wrapper封装着一个Servlet .
也就是Servlet的init方法调用具体实现时在StandardServlet类的intiServlet方法中具体实现的。
ServletContext时Tomcat中的Context的门面类ApplicationContextFacade.


Tomcat中的 Container容器装配结构图
2、HttpServlet

HttpServlet基于Http协议的Servlet基类,HttpServlet重写了service方法。具体处理交给了doPost、doPut、doGet和doDelete等方法处理
package javax.servlet.http;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.util.Enumeration;
import java.util.ResourceBundle;
import javax.servlet.*;
public abstract class HttpServlet extends GenericServlet
{
private static final String METHOD_DELETE = "DELETE";
private static final String METHOD_HEAD = "HEAD";
private static final String METHOD_GET = "GET";
private static final String METHOD_OPTIONS = "OPTIONS";
private static final String METHOD_POST = "POST";
private static final String METHOD_PUT = "PUT";
private static final String METHOD_TRACE = "TRACE";
private static final String HEADER_IFMODSINCE = "If-Modified-Since";
private static final String HEADER_LASTMOD = "Last-Modified";
private static final String LSTRING_FILE =
"javax.servlet.http.LocalStrings";
private static ResourceBundle lStrings =
ResourceBundle.getBundle(LSTRING_FILE);
public HttpServlet() { }
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_get_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
} else {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
}
}
protected long getLastModified(HttpServletRequest req) {
return -1;
}
protected void doHead(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
NoBodyResponse response = new NoBodyResponse(resp);
doGet(req, response);
response.setContentLength();
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_post_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
} else {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
}
}
protected void doPut(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_put_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
} else {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
}
}
prot

最低0.47元/天 解锁文章
1557

被折叠的 条评论
为什么被折叠?



