0%

Servlet 知识梳理

Java Servlet 是 java web 开发的一套解决方案,一套接口定义。Servlet 程序在服务器端运行,动态地生成 Web 页面。运行 Servlet 程序的服务器叫做 Servlet 容器。

常见的容器有

  • Tomcat:由Apache开发的开源免费服务器;
  • Jetty:由Eclipse开发的开源免费服务器;
  • GlassFish:一个开源的全功能JavaEE服务器。
  • 还有其他的商业服务器。Oracle的WebLogic,IBM的WebSphere

项目结构

maven 项目结构,打包生成 war 包进行部署。web.xml 是 web 应用的配置文件。

项目基本结构

容器

  • web容器在启动时,为每个微博应用程序创建一个对应的ServletContext,代表当前的 web 应用

  • 一个web应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通信

  • 应用:

    • 获取 web 应用的全局初始化参数
    • 通过ServletContext实现数据共享
    • 利用ServletContext读取资源文件
servlet容器结构

加载顺序

web 容器的加载顺序 ServletContext –> context-param –> listener –> filter –> servlet

这些元素可以配置在 web.xml 文件中的任意位置,不会因为 filter 在 web.xml 文件中写在 listener 前面就先加载 filter 。

加载过程顺序如下:

  • 启动一个 web 项目,web 容器会读取它的配置文件 web.xml,读取 listener 和 context-param 两个结点。
  • 创建一个 ServletContext ( Servlet 上下文),这个 web 项目的所有部分都将共享这个上下文
  • 容器将 context-param 转换为键值对,并交给 ServletContext
  • 容器创建 listener 中的类实例,创建监听器
  • 容器创建 filter 实例
  • servlet 实例在第一次请求的时候才会创建实例,然后 init() 初始化。(在 web.xml 中配置 load-on-startup 标签后,会在应用启动后就初始化)

Servlet 生命周期

Servlet 生命周期的三个核心方法分别是 init() , service()destroy()。每个Servlet都会实现这些方法,并且在特定的运行时间调用它们。

init

在 Servlet 生命周期的初始化阶段,web容器通过调用 init() 方法来初始化Servlet实例,并且可以传递一个实现 javax.servlet.ServletConfig 接口的对象给它。这个配置对象使 Servlet 能够读取在 web 应用的 web.xml 文件里定义的名值(name-value)初始参数。这个方法在Servlet实例的生命周期里只调用一次

service

web 容器调用 Servlet 的 service() 方法来处理每一个请求service() 方法定义了能够处理的请求类型并且调用适当方法来处理这些请求。编写Servlet的开发者必须为这些方法提供实现。如果发出一个Servlet没实现的请求,那么父类的方法就会被调用并且通常会给请求方(requester)返回一个错误信息。

destroy

web 容器调用 destroy() 方法来终结 Servlet。如果你想在 Servlet 的生命周期内关闭或者销毁一些文件系统或者网络资源,你可以调用这个方法来实现。destroy() 方法和 init() 方法一样,在 Servlet 的生命周期里只能调用一次。

配置

load-on-startup tomcat启动时就创建对象,大于0,多个Servlet的话按照数字从小到大创建

Servlet实例是在Tomcat中创建,Tomcat只创建一个实例,因此是单例的。

Filter

Filter可认为是Servlet的一种“加强版”,主要用于对用户请求request进行预处理,也可以对Response进行后处理,是个典型的处理链。

使用Filter的完整流程是:Filter对用户请求进行预处理,接着将请求HttpServletRequest交给Servlet进行处理并生成响应,最后Filter再对服务器响应HttpServletResponse进行后处理。FilterServlet具有完全相同的生命周期。

换种说法,Servlet里有requestresponse两个对象,Filter能够在一个request到达Servlet之前预处理request,也可以在离开Servlet时处理responseFilter其实是一个Servlet链。

以下是Filter的一些常见应用场合,

  • 认证Filter
  • 日志和审核Filter
  • 图片转换Filter
  • 数据压缩Filter
  • 密码Filter
  • 令牌Filter
  • 触发资源访问事件的Filter
  • XSLT Filter
  • 媒体类型链Filter

Filter可负责拦截多个请求或响应;一个请求或响应也可被多个Filter拦截。

Filter 生命周期

init

在应用启动的时候就进行装载 Filter 类,容器创建好 Filter 对象实例后,调用 init() 方法。接着被 Web 容器保存进应用级的集合容器中去了等待着,用户访问资源。

doFilter

当用户访问的资源正好被 Filter 的url-pattern拦截时,容器会取出 Filter 类调用 doFilter() 方法,下次或多次访问被拦截的资源时,Web 容器会直接取出指定 Filter 对象实例调用 doFilter() 方法。

destroy

当应用服务被停止或重新装载了,则会执行 Filter 的 destroy() 方法,Filter 对象销毁。

配置

当有多个过滤的url-pattern一样时,过滤器的先后和配置的先后保持一致
FilterChain:过滤器链,当有多个过滤器配置了相同的url-pattern时,每个过滤器就像链子一样串联起来,如MyFilter–>MyFilter2—>MyFilterN,
当执行完第一个过滤器的时候通过调用chain.doFilter(request, response)来执行过滤器链中的下一个过滤器的 doFilter() 方法

filter-mapping 标签中 dispatcher

指定过滤器所拦截的资源被 Servlet 容器调用的方式,可以是REQUEST,INCLUDE,FORWARDERROR之一,默认REQUEST。用户可以设置多个子元素用来指定 Filter 对资源的多种调用方式进行拦截。

REQUEST:

当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcherinclude()forward()方法访问或ERROR情况时,那么该过滤器就不会被调用。

INCLUDE:

如果目标资源是通过RequestDispatcherinclude()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。

FORWARD:

如果目标资源是通过RequestDispatcherforward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。

ERROR:

如若在A.jsp页面page指令中指定了error属性=examError.jsp,那么A.jsp中若出现了异常,会跳转到examError.jsp中处理。而在跳转到examError.jsp时,若过滤器配置了ERRORdispather那么则会拦截,否则不会拦截。

Listener

Listener 是用来监听 web 工程状态改变的一种实现机制

  • 监听整个web工程:

    • ServletContextListener
    • ServletContextAttributeListener
  • 监听session范围

    • HttpSessionListener
    • HttpSessionAttributeListener
  • 监听request范围:

    • ServletRequestListener
    • ServletRequestAttributeListener

listener为web应用程序定义监听器,监听器用来监听各种事件,比如:ApplicationSession事件,所有的监听器按照相同的方式定义,功能取决去它们各自实现的接口,常用的Web事件接口有如下几个:

  • ServletContextListener:用于监听Web Application的启动和关闭;
  • ServletContextAttributeListener:用于监听ServletContext范围(Application)内属性的改变;
  • ServletRequestListener:用于监听用户的请求;
  • ServletRequestAttributeListener:用于监听ServletRequest范围(Request)内属性的改变;
  • HttpSessionListener:用于监听用户session的开始和结束;
  • HttpSessionAttributeListener:用于监听HttpSession范围(Session)内属性的改变。

<listener>主要用于监听Web应用事件,其中有两个比较重要的Web应用事件:Application的启动和停止(starting up or shutting down)和Session的创建和失效(created or destroyed)。

Application启动事件发生在应用第一次被Servlet容器装载和启动的时候;停止事件发生在Web应用停止的时候。Session创建事件发生在每次一个新的Session创建的时候,类似地Session失效事件发生在每次一个Session失效的时候。

容器注册监听器的方式有三种:

  1. 利用 @WebListener 注解。
  2. web.xml应用部署文件里注册监听器。
  3. 使用 ServletContext 里定义的 addListener() 方法

其他

RequestDispatcher.forward()转发请求到另一个Servlet

浏览器地址不变

1
2
RequestDispatcher rd = servletContext.getRequestDispatcher("/NextServlet");
rd.forward(request, response);

HttpServletResponse.sendRedirect()重定向请求到另一个Servlet

浏览器地址变成新的servlet

1
httpServletResponse.sendRedirect("/anotherURL");

serlet 3.0注解

  • @WebServlet

  • @WebInitParam

  • @WebFilter

  • @WebListener