Servlet基础



定义

Servlet程序是由服务器调用和执行的类,其可以看作是运行在服务器上的一个模块,它可以接收从客户端传递过来的数据,对数据进行处理后将结果返回给客户端浏览器。

Javax.servlet和Javax.servlet.http包为编写servlet提供了接口和类,所有的servlet必须执行定义了生命周期的servlet接口。

Servlet的主要功能在于交互式地浏览和修改数据,生成动态Web内容。这个工作过程为:

(1)客户端发送请求至服务器

(2)服务器将请求消息发送至Servlet

(3)Servlet生成响应内容并将其传给Server

(4)服务器将响应返回给客户端

下面通过例子说明什么是Servlet,如何在MyEclipse中创建Servlet

例:在test-Hello.jsp中输入一个用户的名字,提交给TestHelloServlet,在页面上输出“你好!欢迎使用Servlet”字符串

从上面代码可以看出,Servlet就是一个Java类,但要将这个类发布到Web服务器中,需要在服务器中建立并配置文件web.xml,因为Tomcat服务器通过读取web.xml创建并运行servlet。

在Eclipse或MyEclipse集成开发工具中,该Web.xml文件会在创建Servlet时自动生成。程序员只需根据实际情况对其进行适当修改即可,这极大方便了软件的开发。

发布后,测试

doGet和doPost方法分别对应HTTP协议的GET和POST请求方法


生命周期

运行在Web服务器中的Servlet是Web服务器进程的一部分,Web服务器负责它的加载和实例化、初始化、调用和销毁。

1、加载和实例化

当启动Servlet容器(Tomcat)时,容器首先到发布目录的WEB-INF下查找web.xml,这个配置文件中有相关的Servlet的的定义和其映射。

Servlet容器会为每个配置自动装入选项的Servlet创建一个实例,而没有设置自动装入选项的Servlet,只有在第一次请求时容器才为其创建实例。为了能让容器创建实例,每个Servlet类必须有一个public的五参数构造函数。通常,在设计Servlet类时不创建构造函数,而是使用默认的构造函数。

2、初始化

当Servlet被实例化后,Servlet容器将调用每个Servlet的init()方法来为实例进行初始化。其中作为init()方法参数的ServletConfig类中定义了初始化Servlet需要的所有参数。init()方法对于一个Servlet只可以被调用一次。

一般情况下,Servlet容器在启动时并不立即初始化所有的Servlet,只有服务器接收到某个客户端发送请求时才初始化这个Servlet。

3、服务

Servlet被初始化后,就处于能响应请求的就绪状态。当客户的请求到来时,服务器创建一个请求对象和一个响应对象。每个Servlet的请求都会产生一个Servlet Request对象,Servlet给客户端的响应由一个Servlet Response对象来完成,这两个对象以参数的形式传给service()方法。在service()内,对客户端的请求方法进行判断,如果是以GET方法提交的,则调用doGet()方法处理请求,如果是以POST方法提交的,则调用doPost()方法处理请求。

4、销毁

Servlet实例是由Servlet容器创建的,所以实例的销毁也是由容器来完成的。当Servlet容器不再需要某个Servlet实例时,容器会调用该Servlet的destroy()方法来释放掉所有初始化时申请的资源。


体系结构和层次结构

1、Servlet体系结构

Servlet容器启动会自动加载Servlet,HTTP Servlet使用HTTP响应标题与客户端进行交互。因此,Servlet容器支持所有HTTP协议的请求和响应,Servlet应用程序体系结构如图:

上图说明客户端的请求首先提交给HTTP服务器进行处理,HTTP服务器只负责静态HTML页面的解析,对于Servlet的请求转交给Servlet容器,在Servlet容器内会根据web.xml文件中的映射关系,调用具体的Servlet,如果Servlet要用到数据库中的信息,可通过JDBC访问数据库。Servlet将处理的结果返回给HTTP服务器,HTTP服务器将生成的HTML页面返回给客户端浏览器。

从图中可以看出JSP和Servlet都是运行在服务器端的程序。

2、Servlet API层次结构

Servlet API包含于两个包中,即javax.servlet和javax.servlet.http。

javax.servlet包的主要类和接口:

(1)接口

Servlet:定义了所有Servlet必须实现的方法

ServletResponse:此接口定义了一个对象 ,由Servlet用于向客户端发送响应

ServletRequest:定义了向Servlet容器传递请求信息的对象

ServletContext:定义了一系列方法,以便Servlet与其运行环境通信

ServletConfig:该接口由Servlet引擎用在Servlet初始化时,向Servlet传递信息

(2)类

GernericServlet:该类实现了Servlet接口,定义了一个通用的、与协议无关的Servlet

ServletInputStream:定义了一个输入流,用于由Servlet从中读取客户请求的二进制数据

ServletOutputStream:定义了一个输出流,用于由Servlet向客户端发送二进制数据

Javax.servlet.http包的主要类和接口。

(1)接口

HttpServletResponse:该接口继承了ServletResponse,向客户端发送响应

HttpServletRequest:该接口继承了ServletResquest接口,为HTTPServlet提供请求信息

HTTPSession:该接口为维护HTTP用户的会话状态提供支持

(2)类

Cookie:用于在Servlet中使用Cookie技术

HttpServlet:该类定义了一个抽象类,它继承自GernericServlet类,应被所有的Servlet继承。


Servlet与JSP的关系

Servlet是JSP的基础,在执行JSP前首先将JSP翻译成Servlet,然后再执行Servlet,所以一个JSP对应一个Servlet。

Web应用项目中的JSP对应的Servlet源码,我们可以在Tomcat的安装目录\Apache Software Foundation\Tomcat 8.0\work\Catalina\localhost下对应目录查看。


Servlet API

javax.servlet.http是javax.servlet包的扩展,Servlet主要应用于HTTP 方面编程,因此javax.servlet.http包内的很多类、接口都是在javax.servlet包相对应的接口基础上添加HTTP/1.1协议的支持而编写的。HttpServlet类是其中最主要的类,如果理解了HttpServlet类和接口HttpServletRequest、HttpServletResponse之间的关系也就理解了Servlet的工作过程。

1、HttpServlet类

该类是Servlet容器中最重要的一个类,其主要功能是处理Servlet请求和响应处理结果。HttpServlet首先须读取Http请求的内容。Servlet容器负责创建HttpServlet对象,并把Http请求封装到HttpServlet对象中,这样可以简化HttpServlet解析请求数据的工作量。Sevlet 容器响应Web客户请求的过程:

(1)

2、ServletRequest接口

ServletRequest接口是HttpServletRequest接口的父接口,在这个接口中定义了一些获取请求数据的方法。

public Enumeration getAttributeNames():获取当前HTTP请求过程中所有请求变量的名字。

public String getCharacterEncoding():获取客户端请求的字符集编码。

public String getContentType():获取HTTP请求的类型,返回值是MIME类型的字符串,如text/html。

public void setAttribute(String name,Object o):设定当前HTTP请求过程请求变量的值,第一个参数是请求变量的名称,第二个是请求变量的值,若已存在同名的请求变量,其值会被覆盖。

public Object getAttribute(String name):获取当前请求变量的值,参数是请求变量的名称。

public String getParameter(String name):获取客户端通过HTTP POST/GET方式传递来的参数的值。

public String[] getParameterValues(String name):若客户端传递来的参数中,某个参数有多个值(复选框),可用该方法获得一个字符串数组。

public String getRemoteAddr():返回当前会话中客户端的IP地址。

public String getScheme():获取客户端发送请求的模式,返回值可以是HTTP、HTTPS、FTP等。

public String getServerName():获取服务器的名称。

public int getServerPort():获取服务器响应请求的端口号。

其它方法的介绍可以查看帮助文档

3、HttpServletRequest接口

HttpServletRequest接口继承自ServletRequest接口,在其中自定义了一些方法,增加对HTTP/1.1的支持

public Cookie[] getCookies():获取当前会话过程中所有的存在Cookie对象,返回值是一个Cookie类型的数组。

public String getHeader(String name):获取特定的HTTP Header的值。

public String getServletPath():获取当前Servlet程序的真实路径。

例:通过HttpServletRequest接口输出客户端和服务器的相关信息

测试

4、ServletResponse接口

该接口可以发生MIME编码数据到客户端,服务器在Servlet程序初始化以后,会创建该接口对象,作为参数传递给service()方法,该接口的主要方法有:

(1)public String getCharacterEncoding():获取向客户端发送数据的MIME编码类型,如text/html等。

(2)public ServletOutputStream getOutputStream():返回一个ServletOutputStream对象,此对象可用于向客户端输出二进制数据。

(3)public PrintWriter getWriter():可以打印各种数据到客户端。

(4)puble void setContentType(String type):指定向客户端发送内容的类型,如:setContentType("text/html")。

5、HttpServletResponse接口

该接口继承自ServletResponse接口,在此基础上,增加了对HTTP/1.1支持的一些方法,在该接口中主要定义的方法有:

(1)public void addCookie(Cookie cookie):该方法的作用是添加一个Cookie对象到当前会话中。

(2)public void sendRedirect(String location):使当前页面重定向到另一个URL。

例:通过Servlet程序获取客户端的cookie和在客户端创建cookie

web.xml中增加相应代码如下:

测试

5、ServletContext接口

该接口定义了一系列方法用于与相应的Servlet容器通信。每个Web应用只有一个ServletContext实例,通过该接口可以访问Web应用的所有资源,也可以用于不同的Servlet间的数据共享,但不能与其他Web应用交换信息。

(1)public ServletContext getContext(String uripath):返回一个指定URL地址的一个子ServletContext对象。

(2)public Set getResourcePaths(String path):返回存储在Web应用中的所有资源路径的Set(集合),这个Web应用的子路径必须和参数提供的匹配。以/结尾表示一个子目录,以/开头表示一个对于当前Web应用的相对路径。

(3)public String getRealPath(String path):返回一个指定虚拟路径的真实路径的字符串。

(4)public Object getAttribute(String name):返回保存在Servlet容器中变量的值,如果无该变量返回null。

(4)public void setAttribute(String name,Object object):在Servlet容器中创建一个名为name,值为object的变量,如果该变量已经存在,则用新值覆盖原来的值。

例:通过ServletContext输出Web服务的资源列表和服务器的根目录

测试