1.首先我们先看看Servlet的类结构图,然后再分别介绍其中的接口方法

由上图可以看到,Servlet和ServletConfig都是顶层接口类,而GenericServlet实现了这两个顶层类,然后HttpServlet实现了GenericServlet类.所以要实现一个Servlet直接就可以继承HttpServlet.

2.Servlet接口代码

public interface Servlet {
//容器在启动的被调用,仅调用一次
void init(ServletConfig var1) throws ServletException;
//获取Servlet配置
ServletConfig getServletConfig();
//处理具体请求
void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
//获取Servlet的相关信息
String getServletInfo();
//Servlet销毁后释放资源
void destroy();
}

其中,init方法接收一个ServletConfig参数,由容器传入.ServletConfig就是Servlet的配置,在web.xml中定义Servlet时通过init-param标签配置的参数由ServletConfig保存.

3.ServletConfig接口定义

public interface ServletConfig {
//用于获取Servlet名,web.xml中定义的servlet-name
String getServletName();
//获取应用本身(非常重要)
ServletContext getServletContext();
//获取init-param中的配置参数
String getInitParameter(String var1);
//获取配置的所有init-param名字集合
Enumeration<String> getInitParameterNames();
}

ServletConfig是Servlet级别,而ServletContext是Context(也就是Application)级别.ServletContext通常利用setAttribute方法保存Application的属性.

4.Servlet第一个实现类GenericServlet

GenericServlet是Servlet的默认实现,是与具体协议无关的,主要做了三件事.

1) 实现了ServletConfig接口,可以调用ServletConfig里面的方法.

public abstract class GenericServlet implements Servlet, ServletConfig, Serializable

2) 提供了无参的init方法

public void init() throws ServletException {}

3)提供了2个log方法,一个记录日志,一个记录异常.

public void log(String msg) {
this.getServletContext().log(this.getServletName() + ": " + msg);
} public void log(String message, Throwable t) {
this.getServletContext().log(this.getServletName() + ": " + message, t);
}

5.基于协议的HttpServlet

HttpSerVlet是基于Http协议实现的Servlet基类,我们在写Servlet的时候直接继承它就行了.SpringMVC中的DispatchServlet就是继承了HttpServlet.HttpServlet重新了service方法,而service方法首先将ServletRequest和ServletResponse转成HttpServletRequest和HttpServletResponse,然后根据Http不同类型的请求,再路由到不同的处理方法进行处理.

public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
HttpServletRequest request;
HttpServletResponse response;
try {//直接对请求类型进行强转
request = (HttpServletRequest)req;
response = (HttpServletResponse)res;
} catch (ClassCastException var6) {
throw new ServletException("non-HTTP request or response");
}
//调用Http的请求方法处理
this.service(request, response);
}
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getMethod();//获取请求类型
long lastModified;
//根据请求类型进行路由
if(method.equals("GET")) {
lastModified = this.getLastModified(req);
if(lastModified == -1L) {
this.doGet(req, resp);
} else {
long ifModifiedSince;
try {
ifModifiedSince = req.getDateHeader("If-Modified-Since");
} catch (IllegalArgumentException var9) {
ifModifiedSince = -1L;
} if(ifModifiedSince < lastModified / 1000L * 1000L) {
this.maybeSetLastModified(resp, lastModified);
this.doGet(req, resp);
} else {
resp.setStatus(304);
}
}
} else if(method.equals("HEAD")) {
lastModified = this.getLastModified(req);
this.maybeSetLastModified(resp, lastModified);
this.doHead(req, resp);
} else if(method.equals("POST")) {
this.doPost(req, resp);
} else if(method.equals("PUT")) {
this.doPut(req, resp);
} else if(method.equals("DELETE")) {
this.doDelete(req, resp);
} else if(method.equals("OPTIONS")) {
this.doOptions(req, resp);
} else if(method.equals("TRACE")) {
this.doTrace(req, resp);
} else {
String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[]{method};
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(501, errMsg);
}
}

Servlet源码级别进行详解的更多相关文章

  1. Android源码下载方法详解

    转自:http://www.cnblogs.com/anakin/archive/2011/12/20/2295276.html Android源码下载方法详解 相信很多下载过内核的人都对这个很熟悉 ...

  2. 【Java】HashMap源码分析——常用方法详解

    上一篇介绍了HashMap的基本概念,这一篇着重介绍HasHMap中的一些常用方法:put()get()**resize()** 首先介绍resize()这个方法,在我看来这是HashMap中一个非常 ...

  3. 【转】ANDROID自定义视图——onMeasure,MeasureSpec源码 流程 思路详解

    原文地址:http://blog.csdn.net/a396901990/article/details/36475213 简介: 在自定义view的时候,其实很简单,只需要知道3步骤: 1.测量—— ...

  4. Spring Boot源码中模块详解

    Spring Boot源码中模块详解 一.源码 spring boot2.1版本源码地址:https://github.com/spring-projects/spring-boot/tree/2.1 ...

  5. ANDROID自定义视图——onMeasure,MeasureSpec源码 流程 思路详解

    简介: 在自定义view的时候,其实很简单,只需要知道3步骤: 1.测量--onMeasure():决定View的大小 2.布局--onLayout():决定View在ViewGroup中的位置 3. ...

  6. React源码 commit阶段详解

    转: React源码 commit阶段详解 点击进入React源码调试仓库. 当render阶段完成后,意味着在内存中构建的workInProgress树所有更新工作已经完成,这包括树中fiber节点 ...

  7. 【转】ANDROID自定义视图——onLayout源码 流程 思路详解

    转载(http://blog.csdn.net/a396901990) 简介: 在自定义view的时候,其实很简单,只需要知道3步骤: 1.测量——onMeasure():决定View的大小 2.布局 ...

  8. nginx 源码安装配置详解(./configure)

    在"./configure"配置中,"--with"表示启用模块,也就是说这些模块在编译时不会自动构建,"--without"表示禁用模块, ...

  9. vue新手入门之使用vue框架搭建用户登录注册案例,手动搭建webpack+Vue项目(附源码,图文详解,亲测有效)

    前言 本篇随笔主要写了手动搭建一个webpack+Vue项目,掌握相关loader的安装与使用,包括css-loader.style-loader.vue-loader.url-loader.sass ...

随机推荐

  1. Java中Solr集群的测试

    import org.apache.solr.client.solrj.impl.CloudSolrServer; import org.apache.solr.common.SolrInputDoc ...

  2. 搭建Spring所需的各类jar包汇总详解

    Spring jar包官网下载地址:http://repo.spring.io/release/org/springframework/spring/ Spring jar包的描述:针对3.2.2以上 ...

  3. laydate日历控件

    var start = { elem: '#start_0', format: 'YYYY-MM-DD', max: laydate.now(-), istime: false, istoday: f ...

  4. 使用nose_parameterized使unitTest实现参数化

    nose-parameterized是一个针对Python单元测试框架实现参数化的扩展 import unittest # from nose_parameterized import paramet ...

  5. payload有效载荷(转)

    payload 记载着信息的那部分数据.通常在传输数据时,为了使数据传输更可靠,要把原始数据分批传输,并且在每一批数据的头和尾都加上一定的辅助信息,比如这一批数据量的大小,校验位等,这样就相当于给已经 ...

  6. (转)fiddler使用简介--其二

    原文地址:http://www.cnblogs.com/miantest/p/7290176.html 在上一篇中介绍了Fiddler的基本使用方法.通过上一篇的操作我们可以直接抓取浏览器的数据包.但 ...

  7. SecureCRT卡死的问题

    ctrl+s是一个古老的shell控制键,不小心按倒就卡死了.在输入ctrl+q就可以恢复了

  8. $《第一行代码:Android》读书笔记——第13章 Android高级技巧

    (一)全局获取Context 1.创建ApplicationUtil类继承自Application类: public class ApplicationUtil extends Application ...

  9. iOS获取设备IP地址

    项目用到要获取iOS设备的IP地址,有2种方法: 1)第一种比较简单,但是只有当你的设备连接到WIFI时才能获取到IP地址,倘若你的设备用的是流量,那就不行.代码如下: #import <ifa ...

  10. Django框架之HTTP本质

    1.Http请求本质 浏览器(socket客户端): socket.connect(ip,端口) socket.send("http://www.xiaohuar.com/index.htm ...