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. 客户端-服务器通信安全 sign key

    API接口签名校验,如何安全保存appsecret? - 知乎  https://www.zhihu.com/question/40855191 要保证一般的客户端-服务器通信安全,可以使用3个密钥. ...

  2. Testlink安装:Notice:Undefined index: type in C:\inetpub\wwwroot\testlink-1.9.3\install\installCheck.php on line 41

    问题现象:

  3. pycharm中导入自写模块时,模块下出现红线

    问题描述: 在pycharm中导入自己写的模块时,得不到智能提示,并在模块名下出现下红线,但是代码可以执行,错误提示为下图所示: 原因:出现 以上情况,是因为文件目录设置的问题,pycharm中的最上 ...

  4. xml数据发送请求,读取xml

    # coding:utf-8 import requests url = "http://httpbin.org/post" # python3字符串换行,在右边加个反斜杠 bod ...

  5. Retrofit2.2说明-简单使用

    很久前就想学习下Retrofit了,不过总是没有时间,正好最近新项目要用到网络请求,正好研究了下Retrofit2.2的简单使用方法,大致记录如下: Retrofit与okhttp共同出自于Squar ...

  6. Latex排版全解(转)

    Latex排版全解 http://blog.csdn.net/langb2014/article/details/51354238

  7. HAProxy安装及简单配置

    一.HAProxy简介 代理的作用:web缓存(加速).反向代理.内容路由(根据流量及内容类型等将请求转发至特定服务器).转码器(将后端服务器的内容压缩后传输给client端).缓存的作用:减少冗余内 ...

  8. C#数组实践

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cont ...

  9. 【整理学习Hadoop】Hadoop学习基础之二:分布式

      分布式系统就是将系统的应用层,数据层或其它部分构架成分布(物理和逻辑上的都可以)状(通常是网状).分布式系统通常是为了增强系统的可扩展性.稳定性和执行效率.比如在线游戏通常就是分布系统,里面所谓的 ...

  10. rails 下载 send_file

    def download send_file File.join(Rails.root, "public", @doc.link), :filename => @title+ ...