Servlet源码级别进行详解
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源码级别进行详解的更多相关文章
- Android源码下载方法详解
转自:http://www.cnblogs.com/anakin/archive/2011/12/20/2295276.html Android源码下载方法详解 相信很多下载过内核的人都对这个很熟悉 ...
- 【Java】HashMap源码分析——常用方法详解
上一篇介绍了HashMap的基本概念,这一篇着重介绍HasHMap中的一些常用方法:put()get()**resize()** 首先介绍resize()这个方法,在我看来这是HashMap中一个非常 ...
- 【转】ANDROID自定义视图——onMeasure,MeasureSpec源码 流程 思路详解
原文地址:http://blog.csdn.net/a396901990/article/details/36475213 简介: 在自定义view的时候,其实很简单,只需要知道3步骤: 1.测量—— ...
- Spring Boot源码中模块详解
Spring Boot源码中模块详解 一.源码 spring boot2.1版本源码地址:https://github.com/spring-projects/spring-boot/tree/2.1 ...
- ANDROID自定义视图——onMeasure,MeasureSpec源码 流程 思路详解
简介: 在自定义view的时候,其实很简单,只需要知道3步骤: 1.测量--onMeasure():决定View的大小 2.布局--onLayout():决定View在ViewGroup中的位置 3. ...
- React源码 commit阶段详解
转: React源码 commit阶段详解 点击进入React源码调试仓库. 当render阶段完成后,意味着在内存中构建的workInProgress树所有更新工作已经完成,这包括树中fiber节点 ...
- 【转】ANDROID自定义视图——onLayout源码 流程 思路详解
转载(http://blog.csdn.net/a396901990) 简介: 在自定义view的时候,其实很简单,只需要知道3步骤: 1.测量——onMeasure():决定View的大小 2.布局 ...
- nginx 源码安装配置详解(./configure)
在"./configure"配置中,"--with"表示启用模块,也就是说这些模块在编译时不会自动构建,"--without"表示禁用模块, ...
- vue新手入门之使用vue框架搭建用户登录注册案例,手动搭建webpack+Vue项目(附源码,图文详解,亲测有效)
前言 本篇随笔主要写了手动搭建一个webpack+Vue项目,掌握相关loader的安装与使用,包括css-loader.style-loader.vue-loader.url-loader.sass ...
随机推荐
- mysql_用户_操作
一. 创建用户 登录MySQL mysql -u root -p 添加新用户 create user 'username'@'host' identified by 'password'; usern ...
- 学习 《UNIX网络编程》
学习本书之前,为了了解C语言,先通读了<C程序设计语言>.但对C语言的理解.熟悉可能还是不足,所以在学习本书的过程中,遇到看不懂的C代码,还要去查询.思考. 本书一开始,我就遇到了问题,运 ...
- /cloudmonitor.log 主机监控
989866842 INFO 2018-09-30 01:38:58.58 [ricGatherServiceHttp] 提交指标完成,耗时:18ms. SystemInfo [serialNumbe ...
- 基于Mesos和Docker的分布式计算平台
基于Mesos和Docker的分布式计算平台 http://www.csdn.net/article/2015-06-09/2824906
- jq cookie
//$.cookie("xx");//读取xx的值 //$.cookie("xx","123");//设置xx的值为123 //$.cook ...
- Python里面如何拷贝一个对象?
import copy lst=[1,2,3,4,[1,2]] # 复制列表lst,命名lst2 lst2=copy.copy(lst) print(f'这是lst3:{lst2}') # 深拷贝 l ...
- servlet 3.0 的新特性之三对异步处理的支持
一.异步处理 1. 什么是异步处理 原来,在服务器没有结束响应之前,浏览器是看不到响应内容的!只有响应结束时,浏览器才能显示结果! 现在异步处理的作用:在服务器开始响应后,浏览器就可以看到响应内容,不 ...
- PyQt4设置窗口左上角的小图标
# -*- coding: utf-8 -*- """ ------------------------------------------------- File Na ...
- driver.close()和driver.quit()
driver.close()关闭当前窗口 driver.quit()退出驱动关闭所有窗口 from selenium import webdriver from time import sleep d ...
- Service degrade
服务降级:主要是针对非正常情况下的应急服务措施;比如电商平台,在针对618.双11等高峰情形下采用部分服务不出现或者延时出现的情形. 为什么是非正常情况下呢,比如我要出差,如果经常出差的话,要带的衣服 ...