本文主要讲Servlet的基础知识和背景知识。

1 CGI简介

CGI(Common Gateway Interface 公共网关接口)是WWW技术中最重要的技术之一,有着不可替代的重要地位。CGI是外部应用程序(CGI程序)与WEB服务器之间的接口标准,是在CGI程序和Web服务器之间传递信息的过程。CGI规范允许Web服务器执行外部程序,并将它们的输出发送给Web浏览器,CGI将Web的一组简单的静态超媒体文档变成一个完整的新的交互式媒体。

Common Gateway Interface,简称CGI。在物理上是一段程序,运行在服务器上,提供同客户端HTML页面的接口。这样说大概还不好理解。那么我们看一个实际例子:现在的个人主页上大部分都有一个留言本。留言本的工作是这样的:先由用户在客户端输入一些信息,如评论之类的东西。接着用户按一下“发布或提交”(到目前为止工作都在客户端),浏览器把这些信息传送到服务器的CGI目录下特定的CGI程序中,于是CGI程序在服务器上按照预定的方法进行处理。在本例中就是把用户提交的信息存入指定的文件中。然后CGI程序将执行结果返回给服务器(webServer),然后服务器将结果返回给客户端,表示请求的任务已经结束。此时用户在浏览器里将看到“留言结束”的字样,整个过程结束。

2 Web服务器发展历史

通过服务器可以访问静态资源和动态资源。

静态资源就是一些图片、视频等文件。访问流程:读取磁盘文件到内存中--->启动IO流-->将文件内容以字符串形式返回给浏览器。

动态资源是一些代码,需要执行后将结果返回给浏览器端。而要在本地执行对应的代码,就需要有执行环境和标准接口规范(个人理解就是上边的CGI)。

1)早期CGI模式服务器

CGI模式的特点:是将服务端的动态资源基于进程(process)方法来运行。由于进程的执行非常耗费时间,且内存空间浪费,所以效率极其低下。

2)FastCGI模式服务器

所谓的fastCGI的模式其实就是当前的CGI模式中添加的一个pooling(资源池)的概念,在服务器启动时初始化固定的进程来提高处理客服端的请求的速度,但是该方法治标不治本。

3)Servlet模式服务器

技术特点:

与传统的CGI模式不同,Servlet运行模式改为单进程多线程的模式(线程程运行在进程中)。

单进程:服务器;

多线程:服务端的Servlet。

这样就大大提高了运行效率。

3 Servlet简介

Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。

使用 Servlet,您可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。

Java Servlet 通常情况下与使用 CGI(Common Gateway Interface,公共网关接口)实现的程序可以达到异曲同工的效果。但是相比于 CGI,Servlet 有以下几点优势:

  • 性能明显更好。
  • Servlet 在 Web 服务器的地址空间内执行。这样它就没有必要再创建一个单独的进程来处理每个客户端请求。
  • Servlet 是独立于平台的,因为它们是用 Java 编写的。
  • 服务器上的 Java 安全管理器执行了一系列限制,以保护服务器计算机上的资源。因此,Servlet 是可信的。
  • Java 类库的全部功能对 Servlet 来说都是可用的。它可以通过 sockets 和 RMI 机制与 applets、数据库或其他软件进行交互。

4 Servlet架构

下图显示了 Servlet 在 Web 应用程序中的位置。

5 Servlet任务

Servlet 执行以下主要任务:

  • 读取客户端(浏览器)发送的显式的数据。这包括网页上的 HTML 表单,或者也可以是来自 applet 或自定义的 HTTP 客户端程序的表单。
  • 读取客户端(浏览器)发送的隐式的 HTTP 请求数据。这包括 cookies、媒体类型和浏览器能理解的压缩格式等等。
  • 处理数据并生成结果。这个过程可能需要访问数据库,执行 RMI 或 CORBA 调用,调用 Web 服务,或者直接计算得出对应的响应。
  • 发送显式的数据(即文档)到客户端(浏览器)。该文档的格式可以是多种多样的,包括文本文件(HTML 或 XML)、二进制文件(GIF 图像)、Excel 等。
  • 发送隐式的 HTTP 响应到客户端(浏览器)。这包括告诉浏览器或其他客户端被返回的文档类型(例如 HTML),设置 cookies 和缓存参数,以及其他类似的任务。

6 Servlet的继承结构

在Tomcat项目包中,有个lib目录,下边有个servlet-api.jar文件包,该jar包就是Tomcat对Servlet的接口实现。通过解压和反编译后,可以查看里边的实现代码。

解压方式:将jar包扩展名改为rar,然后解压。

反编译方式:通过jd-gui.exe反编译工具实现将class文件反编译为可读的java代码文件。

通过上边解压和反编译,在servlet-api\javax\servlet文件夹下,我们可以看到Servlet.class,其反编译后代码如下:

 package javax.servlet;

 import java.io.IOException;

 public abstract interface Servlet
{
public abstract void init(ServletConfig paramServletConfig)
throws ServletException; public abstract ServletConfig getServletConfig(); public abstract void service(ServletRequest paramServletRequest, ServletResponse paramServletResponse)
throws ServletException, IOException; public abstract String getServletInfo(); public abstract void destroy();
}

GenericServlet.class反编译后代码如下:

 package javax.servlet;

 import java.io.IOException;
import java.io.Serializable;
import java.util.Enumeration; public abstract class GenericServlet
implements Servlet, ServletConfig, Serializable
{
private static final long serialVersionUID = 1L;
private transient ServletConfig config; public void destroy()
{
} public String getInitParameter(String name)
{
return getServletConfig().getInitParameter(name);
} public Enumeration<String> getInitParameterNames()
{
return getServletConfig().getInitParameterNames();
} public ServletConfig getServletConfig()
{
return this.config;
} public ServletContext getServletContext()
{
return getServletConfig().getServletContext();
} public String getServletInfo()
{
return "";
} public void init(ServletConfig config)
throws ServletException
{
this.config = config;
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);
} public abstract void service(ServletRequest paramServletRequest, ServletResponse paramServletResponse)
throws ServletException, IOException; public String getServletName()
{
return this.config.getServletName();
}
}

在servlet-api\javax\servlet\http文件夹下,可以找到HttpServlet.class文件,反编译后内容如下:

 package javax.servlet.http;

 // ...省略代码
import javax.servlet.GenericServlet; public abstract class HttpServlet extends GenericServlet
{
// ...省略代码 protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
// ...省略实现代码
} protected long getLastModified(HttpServletRequest req)
{
return -1L;
} protected void doHead(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
// ...省略实现代码
} protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
// ...省略实现代码
} protected void doPut(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
// ...省略实现代码
} protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
// ...省略实现代码
} private static Method[] getAllDeclaredMethods(Class<?> c)
{
// ...省略实现代码
} protected void doOptions(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
Method[] methods = getAllDeclaredMethods(super.getClass());
// ...省略实现代码
} protected void doTrace(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
String CRLF = "\r\n";
StringBuilder buffer = new StringBuilder("TRACE ").append(req.getRequestURI()).append(" ").append(req.getProtocol());
// ...省略实现代码
} protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
String method = req.getMethod();
long lastModified;
// ...省略实现代码
} private void maybeSetLastModified(HttpServletResponse resp, long lastModified)
{
if (resp.containsHeader("Last-Modified"))
return;
if (lastModified >= 0L)
resp.setDateHeader("Last-Modified", lastModified);
} public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException
{
// ...省略实现代码
}
}

从上边源码中可以发现:

servlet.class文件就是实现SUN公司JavaEE制定的Servlet标准接口的代码;

GenericServlet.class 中间层 抽象类 直接实现Servlet,并没有将Servlet所有方法实现,添加了一些自己的方法;

http目录下的HttpServlet继承了GenericServlet,该主要实现与http协议相关的接口(doPost、doGet、doPut、doDelete)。

GenericServlet存在的原因:解除http协议和Servlet之间的耦合。随着技术发展后续可能会替换http,改为其它协议。这样如果要切换,可复用的部分在GenericServlet中,并不需要重新开发,只需要将httpServlet基于新协议重新开发即可。这就是开闭原则,需要更改时,只需要修改一部分代码即可。

Servlet是基于Http协议的。

参考资料&内容来源:

百度百科:https://baike.baidu.com/item/CGI/607810?fr=aladdin&fromid=6717913&fromtitle=%EF%BC%A3%EF%BC%A7%EF%BC%A9

速学堂:http://www.sxt.cn/tomcat/1-1-1.html

菜鸟教程:http://www.runoob.com/servlet/servlet-intro.html

Servlet学习笔记【1】--- 背景和基础知识(CGI、Web服务器发展史、Servlet简介、任务、继承结构)的更多相关文章

  1. Python基础教程学习笔记:第一章 基础知识

    Python基础教程 第二版 学习笔记 1.python的每一个语句的后面可以添加分号也可以不添加分号:在一行有多条语句的时候,必须使用分号加以区分 2.查看Python版本号,在Dos窗口中输入“p ...

  2. 大数据学习笔记——Java篇之基础知识

    Java / 计算机基础知识整理 在进行知识梳理同时也是个人的第一篇技术博客之前,首先祝贺一下,经历了一年左右的学习,从完完全全的计算机小白,现在终于可以做一些产出了!可以说也是颇为感慨,个人认为,学 ...

  3. Ant学习笔记(1) 基础知识

    Ant Apache Ant 是一个基于 Java的构建工具. 下载Ant google.baidu.Windows用户下载zip格式.解压即可. Windows安装Ant Ant本质上是一个Java ...

  4. 【学习笔记】:JavaScript基础知识超详细总结!

    目录 一.JavaScript的实现 二.JavaScript语言的特点 三.JS与HTML如何结合 四.JS中的数据类型 四.JS的原始数据类型 2.JS的引用数据类型 五.JS引用数据类型之函数 ...

  5. JDBC 学习笔记(一)—— 基础知识 + 分页技术

    本文目录:  1.JDBC简介       2.使用JDBC的步骤——第一个JDBC程序       3.DriverManager ——加载数据库驱动       4.数据库URL ——标识数据库的 ...

  6. sqlserver存储过程学习笔记(一)基础知识篇(全)

    说出来有点丢人,做sqlserver应用系统近一年,竟然没有使用过存储过程,现在就好好的梳理一下对应知识,慢慢让其加入到我的项目中去吧. 存储过程的优点:1.运行效率高,提供了在服务器端快速执行sql ...

  7. 学习笔记:HTML+CSS 基础知识

    1.<q>标签,短文本引用       <q>引用文本</q> <q>标签的真正关键点不是它的默认样式双引号(如果这样我们不如自己在键盘上输入双引号就行 ...

  8. Linux学习笔记05之网络基础知识

    一.OSI参考模型:适用于所有网络,现有模型,后有协议 1.应用层:应用程序.用户接口 2.表示层:编码转换.压缩.解压.加密等 3.会话层:建立.维护.拆除会话 4.传输层规定了应用程序的的接口 协 ...

  9. Hbase学习笔记(安装和基础知识及操作)

    1.Hbase简介 1.面向列的分布式数据库 2. 以HDFS作为文件系统 3. 利用MapReduce处理Hbase中海量数据 4. ZookKeeper作为协调工具 5. sqoop提供Hbase ...

  10. 【C#学习笔记】一、基础知识

    1.1数据类型(P43) 类型 别名 允许的值 sbyte System.SByte -128~127 byte System.Byte 0~255 short System.Int16 -32768 ...

随机推荐

  1. .net 真实代理和透明代理的交互

    .本地代理调用 using System; using System.Runtime.Remoting ; using System.Runtime.Remoting.Services ; using ...

  2. WEB接口测试之Jmeter接口测试自动化 (三)(数据驱动测试) 接口测试与数据驱动

    转载:http://www.cnblogs.com/chengtch/p/6576117.html 1简介 数据驱动测试,即是分离测试逻辑与测试数据,通过如excel表格的形式来保存测试数据,用测试脚 ...

  3. poj 1390 Blocks (经典区间dp 方块消除)

    Blocks Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 4250   Accepted: 1704 Descriptio ...

  4. 计算两个有序数组的第K大数(转)

    传统解法,最直观的解法是O(m+n).直接merge两个数组,然后求第K大的数字. 如果想要时间复杂度将为O(log(m+n)).我们可以考虑从K入手.如果我们每次能够删除一个一定在第K个元素之前的元 ...

  5. 《Android源代码设计模式解析与实战》读书笔记

    1.定义 将对象组合成树形结构以表示"部分-总体"的层次结构,使得用户对单个对象和组合对象的使用具有一致性. 2.使用场景 (1)表示对象的部分-总体层次结构时. (2)从一个总体 ...

  6. asp.net 导出excel 中文乱码解决方法 (转)

    用我转载的上一篇文章 Asp.net中把DataTable或DataGrid导出为Excel 导出的文档,中文有乱码现象,其实要解决中文乱码很简单,设置一下字符集.如下: // 设置编码和附件格式 c ...

  7. java 实现统计某段文字在内容中出现的次数

    http://outofmemory.cn/code-snippet/815/java-zishutongji 一个api,位于apache.commons.lang.StringUtils类下的一个 ...

  8. JDBC技术总结(三)

    1. 数据库连接池 JDBC部分的前两个总结主要总结了一下JDBC的基本操作,而且有个共同点,就是应用程序都是直接获取数据库连接的.这会有个弊端:用户每次请求都需要向数据库获得连接,而数据库创建连接通 ...

  9. 解决scrollView中嵌套viewPager的冲突问题

    很简单,在外层ScrollView中添加android:fillViewport="true"属性,然后给viewPager添加一个固定高度

  10. mysql 主从切换

    4)提升slave为master Stop slave: Reset master; Reset slave all; 在5.6.3版本之后 Reset slave; 在5.6.3版本之前 查看sla ...