Notes

JSP | 01 Servlet 介绍、接口和类

🌸Author Echo Pan


概念

Servlet(Server Applet),全称Java Servlet

Sevlet本质上是一段Java程序或代码,其运行在服务器端,用于响应客户端的请求。

Servlet是继承自HttpServlet类的Java类,通常由三个部分构成:

Servlet和JSP的关系

JSP经过编译后生成的就是Servlet文件,JSP是Servlet的简化;
JSP侧重视图,而Servlet主要用于逻辑控制。

JSP是Java和HTML组合的.jsp扩展文件,Sevlet则是纯Java代码;
JSP中有内置对象,而Sevlet中没有。

Servlet能更好地组织业务逻辑代码,但是HTML代码可读性差、维护困难;
JSP虽然规避了上述劣势,但是由于在HTML中混入大量Java代码,一样不可取。

注:后面学的MVC设计模式能够规避两者的短板。

Servlet 接口和API

Servlet API所在包:

  1. javax.servlet包
    常用的包括 Servlet、ServletRequest、ServletConfig、ServletContext接口 以及抽象类GenericServlet 等.
  2. javax.servlet.http包
    用于支持HTTP的Servlet API.

大概过程:

  当Web容器首次载入一个Servlet文件后,会建立该文件的Servlet接口实例。然后根据Servlet接口设定的初始化配置和其他信息(一般在web.xml中)创建一个ServletConfig实例。通过Servlet接口的init()方法传入该ServletConfig实例完成对Servlet实例的初始化。

  Servlet实例初始化完成后,当收到请求时,Web容器会创建Http请求和响应对象,再通过urlPattern找到对应的Servlet实例,调用其service()方法,传入(Http)ServletRequest(Http)ServletResponse实例。

  Web应用被停止或重新启动之前,Web容器将调用Servlet实例的destroy()方法释放资源并卸载Servlet

Servlet 容器

Servlet容器也叫Servlet引擎,是Web服务器或应用服务器的一部分,为响应和请求提供网络服务。


Servlet运行过程

Servlet 接口

所有的Servlet类都必须实现该接口。

Servlet 接口定义了5个方法,其中3个由Servlet容器调用,2个可以在JavaWeb的程序代码里访问。

  1. init(ServletConfig config)
    负责初始化Servlet对象,在Servlet的整个生命周期中只被调用一次
  2. service(ServletRequest req, ServletResponse res)
    负责响应客户端请求,当用户要求访问特定Servlet对象时调用
  3. destroy()
    负责释放Servlet对象占用的资源,当Servlet对象结束生命周期时调用

  1. getServletConfig()
    返回一个ServletConfig对象,该对象包含Servlet的初始化信息
  2. getServletInfo()
    返回一个字符串,其包含了Servlet创建者、版本和版权等信息

GenericServlet 抽象类

由于Servlet接口编写的Servlet类要实现5个方法,比较麻烦,于是有了GenericServlet抽象类。

该类定义了一个通用的、不依赖具体协议的Servlet,实现了Servlet接口和ServletConfig接口。该类给出了除service()方法以外其他4个方法的简单实现。通过GenericServlet编写Servlet类只需实现service()方法即可。

虽然GenericServletServlet进行了加强,但并不常用。HttpServlet才是今天的主角。


GenericServlet详解

HttpServlet 抽象类

一般,客户端通过HTTP协议访问服务器资源。Sun公司提供了抽象类HttpServlet,它继承自GenericServlet类,用来创建适合Web站点的HTTP Servlet。

针对HTTP1.1定义的7种请求方法,HttpServlet提供了7个处理方法:

doGet(),doPost(),doHead(),doPut(),doDelete(),doTrace(),doOptions()

注:TRACE和OPTIONS做了适当实现;
  其他5个方法只提供了返回HTTP错误的实现。

我们常用的一般是doGet()方法和doPost()方法。

doGet()方法

public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
   // Servlet code
}

doPost()方法

public void doPost(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
   // Servlet code
}

当容器接收到针对HttpServlet对象的请求时,调用过程如下:

  1. 调用Public service()方法
  2. Public service()方法中,将参数类型转换为HttpServletRequestHttpServletResponse,然后将转换后的这两个对象作为参数传递给Protected service()方法
  3. Protected service()方法中,首先调用HttpServletRequest对象的getMethod()方法,获取HTTP请求类型,调用相应的doXxx()方法

因此,在编写HttpServlet的派生类时,一般不用覆写service()方法,而只需要重写相应的doXxx()方法即可。


Servlet接口和类HttpServlet抽象类

与请求和响应相关的接口

HttpServletRequest接口扩展于javax.servlet.ServletRequest接口
HttpServletResponse接口扩展于javax.servlet.servletResponse接口

当容器接收到客户端的请求时,会创建一个ServletRequest对象,用来封装请求的数据,同时创建一个ServletResponse对象,用来封装响应的数据,这两个对象作为参数传入service()方法,Servlet再通过service()方法获取请求和发送响应。

HttpServletRequest接口和HttpServletResponse接口分别继承自ServletRequest接口和ServletResponse接口,并在原有基础上新增了一些方法,比如请求常用的getSession()方法,响应常用的sendRedirect()方法。

ServletConfig 接口 - 配置信息

初始化Servlet对象时,使用ServletConfig对象获取初始化参数(从web.xml中获取)。一个Servlet只有一个ServletConfig对象。

在ServletConfig接口中,定义了4个方法:

  1. getInitParameter() 通过传入的参数名获取对应初始参数值,即web.xml配置中的<init-param>参数或者@WebServlet注解中的initParams属性元素;
  2. getInitParameterNames() 返回一个Enumeration<String>对象,没有参数时返回空值;
  3. getServletContext() 返回当前正在运行的web应用的ServletContext对象;
  4. getServletName() 返回Servlet实例的名称,即web.xml配置中的<servlet-name>@WebServlet中的name属性,未配置时返回该实例的类名(可通过xxx.class.getName()获取)。

注:上面提到的配置文件和注解相关的知识会在后面说


ServletConfig详解

ServletContext 接口 - Servlet上下文

Web容器会为每个Web应用创建一个唯一的上下文对象,应用中的所有Servlet共享该对象,不同Servlet之间可以通过该对象实现资源传递和共享,因此ServletContext对象也被称为Context域对象。

我们可以通过4种方式获取ServletContext对象:

//1.GenericServlet 的 getServletContext 方法
ServletContext servletContext = this.getServletContext();
//2.ServletConfig 的 getServletContext 方法
ServletContext servletContext = this.getServletConfig().getServletContext();

//下面的方法暂作了解即可
//3.HttpSession 的 getServletContext 方法
ServletContext servletContext = request.getSession().getServletContext();
//4.HttpServletRequest 的 getServletContext 方法
ServletContext servletContext = request.getServletContext();

通过ServletContext对象,我们可以获取初始化参数、Web应用中的文件以及实现Servlet之间的数据传递。


ServletContext接口详解

RequestDispatcher 接口 - 请求转发

通过RequestDispatcher对象实现请求转发。

获取转发对象的方法

  1. ServletRequest接口的RequestDispatcher() 方法
  2. ServletContext接口的getNamedDispatcher() 方法
  3. ServletContext接口的getRequestDispatcher() 方法

转发请求的方法

  1. forward() 方法
    将客户端请求转发给其他server资源(servlet、jsp、html)处理并返回响应,原网页停止执行,浏览器地址不变
  2. include() 方法
    在处理客户端请求时,同时添加其他server资源并返回响应,原网页可以继续输出响应信息,浏览器地址不变
//forward() 方法
public void forward(ServletRequest request, ServletResponse response)
   throws ServletException, IOException;

//include() 方法
public void include(ServletRequest request, ServletResponse response)
   throws ServletException, IOException;

RequestDispatcher源码解析


上一章:00.开始之前

下一章:02.Servlet生命周期

返回目录