?
?
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