Servlet, 这个词对java程序员并不陌生,我想几乎每个java程序员在学习J2EE知识时,首先学习的就是servlet,这是一种正确的学习方式,在我看来Servlet是J2EE的基础,要熟练的掌握J2EE,必须深刻的了解Servlet的原理,因为你想想,现在只要是web相关的技术或框架,无论是开源的、非开源的,哪个和Servlet没有关系? Spring MVC、Struts、WebWork、SiteMesh等框架都是在Servlet的基础上搭建起来的,要想深刻的了解这些框架 , 熟练的运用这些框架,首先就要理解Servlet原理,明白Servlet的规范。下面一系列文章,将描述一些我对Servlet相关的了解. 首先,让我们理解几个概念?
什么是Servlet?
Servlet 是一种基于java技术的web组件,是一种基于java的且与第三方平台无关的类。通常,它可以被Web 服务器编译、加载和运行,最后生成动态的资源内容。
什么是Servlet容器?
Servlet 容器通常是web 服务器中的一部分,或者说是它的一个组件,Sevlet容器通常提供了一些如接收客户端请求、给出响应等网络请求服务,通常,Servlet容器通过Servlet的生命周期来管理所有的Servlet, Tomcat就是一个典型的Servlet容器。
为什么要使用Servlet?
1. Servlet是采用java语言编写,而由java 跨平台性的特点可知,servlet的移植性很好,且servlet API具有完善的标准,几乎所有的主流服务器都支持servlet.
2. 据说,Servlet与传统的CGI(Common Gateway Interface)相比,功能要强大,且处理的请求采用的是线程,而非进程,从而节省大量的资源开销,因此Servlet处理请求更轻量级、更高效
。
Servlet规范API 类图
结合上图,我们了解和明白一些servlet相关的知识
servlet响应client请求的大概步骤
前面我们说过,servlet的作用主要是接受client请求,生成动态内容,然后返回给客户端,那这个处理过程又由哪些步骤组成呢?
首先,client 发送请求到 服务器 web server或servlet容器;
然后,web server 接收client请求,然后根据client请求调用对应的servlet,动态得产生请求的资源;
最后,web server 将资源返回client.
servlet的生命周期
通过上图,可以清楚的知道servlet接口中主要方法有三个,分别是init、service和destroy。让我们结合这三个方法来描述servlet的生命周期: 1, 在servlet容器或web server启动时, 对servlet进行实例化,此时调用servlet的构造方法;servlet实例化后,调用该servlet实例的init方法,对servlet进行一些初始化处理,处理完成后,将该servlet注入到servlet容器中;
2, 当client向web server或servlet容器请求servlet时,web server或servlet容器首先会根据请求的servlet名称去servlet容器中找对应的servlet,如果servlet不存在该名称对应的servlet,则向client响应请求不存在等信息,否则进行步骤3;
3, 如果请求的servlet存在于servlet容器,则调用servlet的service方法,生成动态资源,响应给client; (记住,整个过程该servlet只有一个实例,即单例);
4, 当web server退出或servlet容器销毁时,调用servlet的destroy方法,最后唯一的sevlet实例将会被GC.
servlet 规范中各interface的功能职责
Servlet: 这个就不用说了,Servlet的核心,具体Servlet中方法的处理规范可见以上描述的Servlet的生命周期
ServletConfig: 封装了对应的Servlet的相关配置信息,如servlet名字,servlet的初始参数以及Servlet所在的上下文对象,即ServletContext. ServletConfig中的属性通常在Servlet初始化时进行初始化.
ServletRequest: 封装了所有来自client端的请求信息,如请求参数、cookie、attribute、请求类型、请求方式(安全还是非安全等)等,同时ServletRequest中的还需要明确指定部分属性,如 请求内容的编码(可以自己设定)等. 进一步的解释,可以参照下一章对HttpServletRequest的分析.
ServletResponse: 封装了server端资源到client端的所有相关信息,如 资源传输的buffer信息、响应的url地址信息、资源的编码信息等.
ServletInputStream/BufferedReader: 读取ServletRequest所封装的信息的I/O接口,
ServletInputStream,采用字节流的方式读取;BufferedReader,采用字符流的方式读取.
ServletOutputSteam/PrintWriter: 将资源写入到client的I/O接口.
ServletOutputSteam,采用字节流的方式进行写入;PrintWriter,采用字符流的方式进行写入.
GenericServlet: 抽象类,它定义了一个Servlet的基本实现,虽然它是Servlet的基本实现,但是它是与协议无关的(即不依赖于http协议,也不依赖于其它应用层协议). 一般,基于协议的Servlet,如httpservlet,通常会继承该类.
RequestDispatcher: 我们在搭建web应用的过程中,可能会有这样的需求: 在当前servlet中处理完成后,需要导向(forwar)另外一个servlet或静态资源(html或text等),或者 是在当前servlet的处理过程中,需要将其它的资源包含(include)到当前的servlet资源里来。而RequestDisaptcher 接口中的forward和inluce方法就提供了实现以上两个需求的机制. 关于RequestDispatcher的详细描述见后面章节.