?
?
DispatcheServlet类图,我们根据其类图进行源码分析
?
GenericServlet?源码分析
?
/**
* 定义一个通用的,协议无关的Servlet.如果需要编写一个在Web中使用的Http Severlet需要继承HttpServlet
* GeneraicServlet实现了Servlet接口和ServletConfig接口。GenericServlet *可以直接通过Servlet扩展,虽然这是比较常见的一种是继承特殊协议的子类,如HttpServlet
* GenericServlet使写Servlet变的更容易。它提供简单的版本的生命周期方法 init,destory和ServletCOnfig接口中的方法
* GenericServlet同样实现了生命在ServeltContext接口中的log方法s
*/
public abstract class GenericServlet
implements Servlet, ServletConfig, java.io.Serializable
{
private static final String LSTRING_FILE = "javax.servlet.LocalStrings";
private static ResourceBundle lStrings =
ResourceBundle.getBundle(LSTRING_FILE);
private transient ServletConfig config;
/**
*无参构造方法
*
*/
public GenericServlet() { }
/**
* 被servlet容器调用,用来指示一个servlet正在停止服务
*
*/
public void destroy() {
}
/**
* 返回一个命名的初始化参数的字符串值,如果这个初始化参数不存在则返回null
* 这个方法对从ServletConfig对象中获指定名称的参数的值提供了便利
*/
public String getInitParameter(String name) {
//获取ServletConfig对象
ServletConfig sc = getServletConfig();
if (sc == null) {
throw new IllegalStateException(
lStrings.getString("err.servlet_config_not_initialized"));
}
// 从servletConfig中获取指定名称初始化参数值
return sc.getInitParameter(name);
}
/**
* 将所有参数名称作为一个Enumeration<String>返回。如果没有初始化参数则返回一个空的Enumration
*/
public Enumeration<String> getInitParameterNames() {
//获取servletConfig对象
ServletConfig sc = getServletConfig();
if (sc == null) {
throw new IllegalStateException(
lStrings.getString("err.servlet_config_not_initialized"));
}
//获取参数名称的枚举
return sc.getInitParameterNames();
}
/**
* 获取一个ServletConfig对象
*/
public ServletConfig getServletConfig() {
return config;
}
/**
*返回一个servlet正在其中运行的ServletContext的引用
*
*
*/
public ServletContext getServletContext() {
ServletConfig sc = getServletConfig();
if (sc == null) {
throw new IllegalStateException(
lStrings.getString("err.servlet_config_not_initialized"));
}
return sc.getServletContext();
}
/**
*返回一个关于serlvet信息,比如 *作者,版本以及版权等。默认情况下,这个方法返回一个空字符串。如果需要返回有意义的值需要重写这个方法
*
*/
public String getServletInfo() {
return "";
}
/**
* 被Servlet容器调用,用来标示一个servlet正准备开始服务
*/
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}
public void init() throws ServletException {
}
public void log(String msg) {
getServletContext().log(getServletName() + ": "+ msg);
}
public void log(String message, Throwable t) {
getServletContext().log(getServletName() + ": " + message, t);
}
/**
* 被servlet容器调用,让一个servlet响应一个请求
* 这是一个抽象方法,所以子类比如HttpServlet必须重写这个方法
*/
public abstract void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException;
/**
* 返回servlet实例的名称
*/
public String getServletName() {
ServletConfig sc = getServletConfig();
if (sc == null) {
throw new IllegalStateException(
lStrings.getString("err.servlet_config_not_initialized"));
}
return sc.getServletName();
}
}
?HttpServlet?源码分析
/**
* 提供了一个抽象类用来被继承创建一个Http servlet来使用一个web站点。
* 一个HttpServlet的子类必须至少重写下述中的一个方法
* doGet,如果servlet支持Http get请求
* doPost,支持http post请求
* doPut, 支持http put请求
* doDelete 支持http delete请求
* init 和destroy 来管理servlet声明周期资源
* getServletInfo,servlet用来提供自身信息
* 几乎没有理由去重写service方法。service方法处理标准的Http请求时通过将其分发给相应请求类型的处理方法。
* Servlet通常运行在多线程服务器上,所以必须注意一个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() { }
/**
* 服务器通过service方法调用处理一个Http的get请求
* 重写这个方法支持get请求同时也自动支持Http Head请求。Head请求是一个响应中没有返回体,只有请求头部字段
*/
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);
}
}
/**
* 返回HttpServletRequest对象的最后修改时间
*/
protected long getLastModified(HttpServletRequest req) {
return -1;
}
protected void doHead(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
NoBodyResponse response = new NoBodyResponse(resp);
//委托给doGet方法
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);
}
}
protected void doDelete(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException
{
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_delete_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
} else {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
}
}
private Method[] getAllDeclaredMethods(Class<?> c) {
if (c.equals(javax.servlet.http.HttpServlet.class)) {
return null;
}
Method[] parentMethods = getAllDeclaredMethods(c.getSuperclass());
Method[] thisMethods = c.getDeclaredMethods();
if ((parentMethods != null) && (parentMethods.length > 0)) {
Method[] allMethods =
new Method[parentMethods.length + thisMethods.length];
System.arraycopy(parentMethods, 0, allMethods, 0,
parentMethods.length);
System.arraycopy(thisMethods, 0, allMethods, parentMethods.length,
thisMethods.length);
thisMethods = allMethods;
}
return thisMethods;
}
/**
* 从公开的service方法中接收标准的HTTP请求,将其分发给相应的处理方法。
*/
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
// 获取请求方法
String method = req.getMethod();
// 如果是get方法
if (method.equals(METHOD_GET)) {
//获取最后修改时间
long lastModified = getLastModified(req);
// 如果最后修改时间未知
if (lastModified == -1) {
//分发给doGet方法处理
doGet(req, resp);
} else {
long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
// 如果servlet最后修改时间小于请求的最后修改时间则调用doGet,否则返回304
if (ifModifiedSince < lastModified) {
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);
}
}
/*
* Sets the Last-Modified entity header field, if it has not
* already been set and if the value is meaningful. Called before
* doGet, to ensure that headers are set before response data is
* written. A subclass might have set this header already, so we
* check.
*/
private void maybeSetLastModified(HttpServletResponse resp,
long lastModified) {
if (resp.containsHeader(HEADER_LASTMOD))
return;
if (lastModified >= 0)
resp.setDateHeader(HEADER_LASTMOD, lastModified);
}
/**
* 将请求委托给给protected void service(HttpServletRequest req, HttpServletResponse resp)
*/
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException
{
HttpServletRequest request;
HttpServletResponse response;
if (!(req instanceof HttpServletRequest &&
res instanceof HttpServletResponse)) {
throw new ServletException("non-HTTP request or response");
}
request = (HttpServletRequest) req;
response = (HttpServletResponse) res;
service(request, response);
}
}
}
?
?HttpServletBean
public abstract class HttpServletBean extends HttpServlet implements EnvironmentAware {
protected final Log logger = LogFactory.getLog(getClass());
/**
* 一组必须为这个servlet提供的配置参数
*/
private final Set<String> requiredProperties = new HashSet<String>();
private Environment environment = new StandardServletEnvironment();
/**
* 强制子类调用这个方法来指定属性,并且必须提供作为作为配置参数。这个方法应该在子类的构造方法中调用y
*/
protected final void addRequiredProperty(String property) {
this.requiredProperties.add(property);
}
/**
* 映射配置参数到这个Servlet bean的书zing同时调用子类的初始化方法
*/
@Override
public final void init() throws ServletException {
if (logger.isDebugEnabled()) {
logger.debug("Initializing servlet ‘" + getServletName() + "‘");
}
// 使用初始化参数设置bean的属性
try {
//创建一个ServletConfigPropertyValues对象
PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
//获取当前对象的BeanWrapper,使用JavaBean风格访问bean的属性
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
//创建一个ServletContextResourceLoader
ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
// 设置bw的属性编辑器
bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, this.environment));
//初始化当前对象的BeanWrapper
initBeanWrapper(bw);
//设置bean属性
bw.setPropertyValues(pvs, true);
}
catch (BeansException ex) {
logger.error("Failed to set bean properties on servlet ‘" + getServletName() + "‘", ex);
throw ex;
}
//调用子类初始化方法
initServletBean();
if (logger.isDebugEnabled()) {
logger.debug("Servlet ‘" + getServletName() + "‘ configured successfully");
}
}
/**
* 对初始化BeanWrapper,可以使用自定义属性编辑器
* 默认实现是一个空方法
*/
protected void initBeanWrapper(BeanWrapper bw) throws BeansException {
}
/**
* 重写方法,如果没有servletConfig 则返回null
*/
@Override
public final String getServletName() {
return (getServletConfig() != null ? getServletConfig().getServletName() : null);
}
@Override
public final ServletContext getServletContext() {
return (getServletConfig() != null ? getServletConfig().getServletContext() : null);
}
/**
*子类通过重写这个方法实现自定义的初始化,在这个方法调用之前,这个Servlet所有bean属性都已经设置好了
*/
protected void initServletBean() throws ServletException {
}
public void setEnvironment(Environment environment) {
this.environment = environment;
}
/**
* 从的ServletConfig初始化参数创建PropertyValues。
*/
private static class ServletConfigPropertyValues extends MutablePropertyValues {
/**
* 创建一个新的ServeltConfigPropertyValues
*/
public ServletConfigPropertyValues(ServletConfig config, Set<String> requiredProperties)
throws ServletException {
//获取所有丢失的参数
Set<String> missingProps = (requiredProperties != null && !requiredProperties.isEmpty()) ?
new HashSet<String>(requiredProperties) : null;
// 获取所有初始化参数名枚举
Enumeration en = config.getInitParameterNames();
//遍历所有初始化参数
while (en.hasMoreElements()) {
String property = (String) en.nextElement();
Object value = config.getInitParameter(property);
//添加到property数组中
addPropertyValue(new PropertyValue(property, value));
if (missingProps != null) {
missingProps.remove(property);
}
}
// 如果依然有丢失的属性则抛出异常
if (missingProps != null && missingProps.size() > 0) {
throw new ServletException(
"Initialization from ServletConfig for servlet ‘" + config.getServletName() +
"‘ failed; the following required properties were missing: " +
StringUtils.collectionToDelimitedString(missingProps, ", "));
}
}
}
}
?
原文:http://zhangwei-david.iteye.com/blog/2222609