【tomcat】04 Servlet规范

一、介绍

百度百科

二、Servlet 接口

1、Servlet规范的核心接口即是Servlet接口,它是所有Servlet类必须实现的接口。

2、Java Servelt API中已经提供了两个抽象类方便开发者实现Servlet类,分别是GenericServlet和HttpServlet。

  1. GenericServlet定义了一个通用的、协议无关的Servlet
  1. HttpServlet则定义了HTTP的Servlet
  1. 两个抽象类可以使Servlet类复用很多共性功能

3、service方法:是处理客户端请求的方法,客户端发起的请求会被路由到对应的Servlet对象上。前面说到的

  1. HttpServlet类的service方法把对HTTP协议的GET、POST、PUT、DELETE、HEAD、OPTIONS、TRACE等请求转发到各自的处理方法中,即doGet、doPost、doPut、doDelete、doHead、doOptions、doTrace等方法。HttpServlet提供了这些共性的处理逻辑,其他继承它的类就不用再各自实现,只需要在对应的方法中做具体的处理逻辑即可。
  1. 例如我们做Web开发时常常会自己定义一个Servlet,并在doGet和doPost方法中做业务逻辑处理。

4、在Servlet容器中,每个Servlet类只能对应一个Servlet对象,所有请求都由同一个Servlet对象处理。

如果Servlet实现了SingleThreadModel接口则可能会在Web容器中存在多个Servlet对象。对于Web容器来说,实现了SingleThreadModel接口意味着一个Servlet对象对应着一个线程,所以此时Servlet的成员变量不存在线程安全问题。

5、Servlet的生命周期

graph LR
A(加载实例化)-->B(初始化)
B(初始化)-->C(处理客户端请求)
C(处理客户端请求)-->D(销毁)
  1. 加载实例化主要由Web容器完成
  1. 其他三个阶段则对应Servlet的init、service和destroy方法。

a) Servlet对象被创建后需要进行初始化操作,初始化工作可以放在以ServletConfig类型为参数的ini方法中,ServletConfig为web.xml配置文件中配置的对应的初始化参数,由Web容器完成web.xml配置读取并封装成ServletConfig对象。

b) Servlet初始化完成后,开始接受客户端的请求,请求被封装成ServletRequest类型的请求对象和ServletResponse类型的响应对象,通过service方法处理请求并响应客户端。

c) 一个Servlet需要从Web容器中移除时,就会调用对应的destroy方法以释放所有的资源,并且调用destroy方法之前要保证所有正在执行service方法的线程都完成执行。

三、ServletRequest接口

1、ServletRequest接口的实现类封装了客户端请求的所有信息。

如果使用HTTP协议通信则包括HTTP的请求行和请求头部
HTTP对应的请求对象类型是HttpServletRequest类

2、ServletRequest接口的实现类中的信息

  1. 一些HTTP请求头部的获取方法,如getHeader、getHeaders和getHeaderNames。
  1. 一些获取请求路径的方法,如getContextPath、getServletPath和getPathInfo,对于路径变量,其中requestURI=contextPath+servletPath+pathInfo,而getRealPath方法则是获取某个相对路径对应的文件系统路径。
  1. 获取Cookie的方法,如getCookies方法;提供了判断标识是否为HTTPS的方法,如isSecure方法。
  1. 获取客户端语言环境的方法,如getLocale和getLocales,它们对应HTTP的Accept-Language头部。
  1. 获取客户端编码的方法,如getCharacterEncoding,对应HTTP协议的Content-Type头部

3、ServletRequest接口的对象只在Servlet的service方法或过滤器的doFilter方法作用域内有效。

  1. 启用了异步处理以调用ServletRequest接口对象的startAsync方法,此时request对象会一直有效,直到调用AsyncContext的complete方法。
  1. Web容器通常会出于性能原因而不销毁ServletRequest接口的对象,而是重复利用ServletRequest接口对象。

四、ServletContext接口

1、ServletContext接口定义了运行所有Servlet的Web应用的视图

  1. Web应用的Servlet全局存储空间,Web应用对应的所有Servlet共有的各种资源和功能的访问。
  1. 获取Web应用的部署描述配置文件的方法,如getInitParameter和getInitParameterNames。
  1. 添加Servlet到ServletContext里面的方法,如addServlet。
  1. 添加Filter(过滤器)到ServletContext里面的方法,如addFilter。
  1. 添加Listener(监听器)到ServletContext里面的方法,如addListener。
  1. 全局的属性保存和获取功能,如setAttribute、getAttribute、getAttributeNames和removeAttribute等。
  1. 访问Web应用静态内容的方法,如getResource和getResourceAsStream,以路径作为参数进行查询,此参数要以“/”开头,相对于Web应用上下文的根或相对于Web应用WEB-INF/lib目录下jar包的META-INF/resources。

2、所有Servlet及它们使用的类需要由一个单独的类加载器加载。

3、每个实现ServletContext接口的对象都需要一个临时存储目录,Servlet容器必须为每个ServletContext分配一个临时目录,并可在ServletContext接口中通过javax.servlet.context.tempdir属性获取该目录。

五、ServletResponse接口

1、ServletResponse接口的对象封装了服务器要返回客户端的所有信息。

如果使用HTTP,则包含了HTTP的响应行、响应头部和响应体。

2、为了提高效率,一般ServletResponse接口对响应提供了输出缓冲。

getBufferSize用于获取缓冲区大小

setBufferSize用于设置缓冲区大小

flushBuffer强制刷新缓冲区

resetBuffer将清空缓冲区中的内容,但不清空请求头部和状态码;

isCommitted判断是否有任何响应字节已经返回给客户端

reset清空缓冲区内容,同时清空头部信息和状态码。

3、ServletResponse接口对应HTTP的实现对象为HttpServletResponse,可以通过setHeader和addHeader方法向HttpServletResponse中添加头部;可以通过sendRedirect将客户端重定向到另外一个地址;可以通过sendError将错误信息输出到客户端。

4、ServletResponse接口关闭时,缓冲区中的内容必须立即刷新到客户端,ServletResponse接口只在Servlet的service方法或过滤器的doFilter方法的作用域内有效,除非它关联的ServletResponse接口调用了startAsync方法启用异步处理,此时ServletResponse接口会一直有效,直到调用AsyncContext的complete方法。Web容器通常会出于性能原因而不销毁ServletResponse接口对象,而是重复利用ServletResponse接口对象。

六、Filter接口

1、Filter接口允许Web容器对请求和响应做统一处理。

如:统一改变HTTP请求内容和响应内容,它可以作用于某个Servlet或一组Servlet。

2、Web应用部署完成后,必须实例化过滤器并调用其init方法。当请求进来时,获取第一个过滤器并调用doFilter方法,接着传入ServletRequest对象、ServletResponse对象及过滤器链(FilterChain),doFilter方法负责过滤器链中下一个实体的doFilter方法调用。当容器要移除某过滤器时必须先调用过滤器的destroy方法。

3、可以用“@WebFilter”注解或部署描述文件定义过滤器,XML配置形式使用元素定义,包括、和子节点,并使用定义Web应用的Servlet和其他静态资源通过过滤器。

七、会话

1、Servlet没有提出协议无关的会话规定,而是每个通信协议自己规定。

  1. HTTP对应的会话接口是HttpSession
  1. Cookie是常用的会话跟踪机制,其中Cookie的标准名字必须为JSESSIONID。
  1. 另外一种会话跟踪机制则是URL重写,即在URL后面添加一个jsessionid参数,当支持Cookie和SSL会话的情况下,不应该使用URL重写作为会话跟踪机制。会话ID通过调用HttpSession.getId()获取,且能在创建后通过调用HttpServletRequest.changeSessionId()改变。
  1. HttpSession对象必须限定在ServletContext级别,会话里面的属性不能在不同ServletContext之间共享。

2、Servlet可将某对象以键值对形式保存到HttpSession中,处于同一个ServletContext和相同会话中的任意Servlet都可以使用会话中保存的对象。

如果某些对象想要在保存到会话或从会话中移除时得到通知,可以让某个对象实现HttpSessionBindingListener接口,里面的valueBound和valueUnbound分别会在对应时刻触发。

3、Servlet容器默认会话的超时时间,可以通过HttpSession的getMaxInactiveInterval方法获取和setMaxInactiveInterval方法设置。

4、分布式环境中,会话的所有请求在同一时间必须仅被一个JVM处理,分布式容器迁移会话时会通知实现了HttpSessionActivationListener接口的所有会话属性。

八、注解

1、Web应用中,使用了注解的类只有被放到WEB-INF/classes目录中或WEB-INF/lib目录下的jar中,注解才会被Web容器处理。web.xml配置文件的元素的metadata-complete默认为false,这表示Web容器必须检查类的注解和Web Fragment,否则忽略注解和Web Fragment。

2、@WebServlet注解

用于在Web项目中定义Servlet,它必须指定urlPatternsvalue属性,默认的name属性为完全限定类名,@WebServlet注解的类必须继承javax.servlet.http.HttpServlet类。

3、@WebFilter注解

用于在Web项目定义Filter,它必须指定urlPatterns、servletNames或value属性,默认的filterName属性为完全限定类名,使用@ WebFilter注解的类必须实现javax.servlet.Filter。

4、@WebInitParam注解

用于指定传递到Servlet或Filter的初始化参数,它是WebServlet和WebFilter注解的一个属性。

5、@WebListener注解用于定义Web应用的各种监听器 必须实现

javax.servlet.ServletContextListener

javax.servlet.ServletContextAttributeListener

javax.servlet.ServletRequestListener

javax.servlet.ServletRequestAttributeListener

javax.servlet.http.HttpSessionListener

javax.servlet.http.HttpSessionAttributeListener

javax.servlet.http.HttpSessionIdListener;

九、可插拔性

1、为了给Web开发人员提供更好的可插拔性和更少的配置,可以在一个库类或框架jar包的META-INF目录中指定Web Fragment,即web-fragment.xml配置文件,它可以看成Web的逻辑分区,web-fragment.xml与web.xml包含的元素基本上都相同。

2、部署期间,Web容器会扫描WEB-INF/lib目录下jar包的META-INF/web-fragment.xml文件,并根据配置文件生成对应的组件。

3、一个Web应用可能会有一个web.xml和若干个web-fragment.xml文件,Web容器加载时会涉及顺序问题。有两种方式定义它们加载的顺序:绝对顺序,web.xml中的元素用于描述加载资源的顺序;相对顺序,web-fragment.xml中的元素用于描述web-fragment.xml之间的顺序。

十、请求分发器

1、负责把请求转发给另外一个Servlet处理,或在响应中包含另外一个Servlet的输出,RequestDispatcher接口提供了此实现机制。

2、用户可以通过ServletContext的getRequestDispatcher方法和getNamedDispatcher方法分别以路径或Servlet名称作为参数获取对应Servlet的RequestDispatcher。

3、请求分发器有include和forward两个方法。

  1. include方法是将目标Servlet包含到当前的Servlet中,主控制权在当前Servlet上。
  1. forward方法是将当前Servlet的请求转移到目标Servlet上,主控权在目标Servlet上,当前Servlet的执行终止。

十一、Web应用

1、Web应用和ServletContext接口对象是一对一的关系,ServletContext对象提供了一个Servlet和它的应用程序视图。

2、Web应用可能包括Servlet、JSP、工具类、静态文件、客户端Java Applet等。Web应用结构包括WEB-INF/web.xml文件、WEB-INF/lib/目录下存放的所有jar包、WEB-INF/classes/目录中存放的所有类、META-INF目录存放的项目的一些信息,以及其他根据具体目录存放的资源。

3、一般WEB-INF目录下的文件都不能由容器直接提供给客户端访问,但WEB-INF目录中的内容可以通过Servlet代码调用ServletContext的getResource和getResourceAsStream方法来访问,并可使用RequestDispatcher调用公开这些内容。

4、Web容器用于加载WAR文件中Servlet的类加载器必须提供getResource方法,以加载WAR文件的JAR包中包含的任何资源。

  1. 容器不允许Web应用程序覆盖或访问容器的实现类。
  1. 一个类加载器的实现必须保证部署到容器的每个Web应用,在调用Thread.currentThread.getContextClassLoader()时返回一个规定的ClassLoader实例。
  2. 部署的每个Web应用程序的ClassLoader实例必须是一个单独的实例。

5、服务器应该能在不重启Web容器的情况下更新一个Web应用程序,而更新Web应用程序时Web容器应该提供可靠的方法保存这些Web应用的会话。

如果调用response的sendError方法或如果Servlet产生一个异常或把错误传播给容器,容器要按照Web应用部署描述文件中定义的错误页面列表,根据状态码或异常试图返回一个匹配的错误页面。如果Web应用部署描述文件的error-page元素没有包含exception-type或error-code子元素,则错误页面使用默认的错误页面。

6、Web应用的部署描述符中可以配置欢迎文件列表。当一个Web的请求URI没有映射到一个Web资源时,可以从欢迎文件列表中按顺序匹配适合的资源返回给客户端,

如欢迎页为index.html,则http://localhost:8080/webapp请求实际变为http://localhost:8080/webapp/index.html。如果找不到对应的欢迎页,则返回404响应。

7、当一个Web应用程序部署到容器中时,在Web应用程序开始处理客户端请求之前,先执行以下步骤

  1. 实例化部署描述文件中元素标识的每个事件监听器的一个实例
  1. 已实例化且实现了ServletContextListener接口的监听器实例,调用contextInitialized()方法。
  1. 实例化部署描述文件中元素标识的每个过滤器的一个实例,并调用每个过滤器实例的init()方法。
  1. 根据load-on-startup 元素值定义的顺序,包含元素的元素为每个Servlet实例化一个实例,并调用每个Servlet实例的init()方法。

十二、Servlet映射

1、对于请求的URL, Web容器根据最长的上下文路径匹配请求URL,匹配Servlet。

2、Servlet的路径是从整个请求URL中减去上下文和路径参数。

3、匹配规则

  1. Web容器尝试匹配一个精确的Servlet路径,如果匹配成功,则选择该Servlet。
  1. Web容器递归尝试匹配最长的路径前缀
  1. 如果URL最后包含扩展名

4、如.jsp, Web容器将试图匹配一个专门用于处理此扩展名的Servlet。如果前三个规则都不匹配,则匹配一个默认的Servlet

十三、部署描述文件

所有Servlet容器的Web应用程序部署描述文件需要支持以下类型的配置和部署信息

Session配置

Servlet声明

Servlet映射

应用程序生命周期监听器类

过滤器定义和过滤器映射

MIME类型映射

欢迎文件列表

错误页面

语言环境和编码映射

安全配置(包括login-config、security-constraint、security-constraint、security-role-ref和run-as)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章