学完JavaWeb阶段有一段时间了,在进入框架学习之前,把JavaWeb三大组件做个总结记录,为框架学习铺点基础.

一、什么是JavaWeb三大组件?

  Servlet,Listener,Filter.它们在JavaWeb开发中分别提供不同的功能.

二、三大组件介绍

  1、Servlet

  1.1 servlet介绍

  广义上说,servlet是运行在web服务器或应用服务器的程序,用来处理客户端请求的动态资源.Servlet = Service + Applet,表示小服务程序。狭义上来说,狭义的Servlet是指Java语言实现的一个接口,该接口有一个实现类为GenericServlet,该实现类有一个子类为HttpServlet,而我们实际开发中用的比较多的,就是我们通过根据具体的业务需求而继承HttpServlet来创建的servlet.

  1.2 创建servlet

  通常来说,创建servlet有三种方式:实现Servlet接口,继承GenericServlet类,继承HttpServlet类.通常最后一种用的比较多,在开发中,可以自己手动地创建servlet,但是要记得配置web.xml(web2.5下).但是通常还是借助eclipse等编辑器快速创建servlet即可.

  1.3 servlet的配置

  简单说就是web2.5的项目中,在web.xml配置文件中的设置修改.在eclipse中,该配置文件的位置是在WebContent/WEB-INF中

 <servlet>
    <description></description>
    <display-name>servlet名称</display-name>
    <servlet-name>servlet名称</servlet-name>
    <servlet-class>servlet的全限定名,即包含了包名了的</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>servlet名称</servlet-name>
    <url-pattern>匹配路径,例如/addServlet</url-pattern>
  </servlet-mapping>

  如果是通过eclipse快速创建的servlet,则web.xml会自动生成以上信息,自己只需要手动地按需求改一下匹配路径就好了,当然不改也没关系.关于这个匹配路径,有几点要注意下,一个是servlet中可以有多条匹配路径与之对应,意思就是说  <url-pattern>匹配路径,例如/addServlet</url-pattern>   这行代码,可以多写几行,里面的匹配路径可以为多个.到时候无论访问哪一个路径,都是会跳转到该servlet的.另外一个就是匹配问题.这里面涉及到完全匹配,目录匹配以及扩展名匹配.这其中完全匹配的优先级最高.需要注意⚠️的是,如果自己手动删除了一个servlet,则需要到web.xml中手动删除相对应的servlet的配置信息,这一步别忘了.

  1.4 Servlet的生命周期

  当我们谈论Servlet时,我们实际上使用的是servlet对象,那么这个对象是什么时候创建和销毁的.这个就是servlet的生命周期.简单来说,Servlet的生命周期可被定义为从创建到毁灭的整个过程.参看以下:

  • Servlet 通过调用 init () 方法进行初始化。
void init(ServletConfig)

  servlet的初始化方法,只在创建servlet实例时候调用一次,Servlet是单例的,整个服务器就只创建一个同类型Servlet,servlet可以在第一次接受请求时被创建,也可以在服务器启动时就被创建.这个时间点的设置,需要在web.xml的<servlet>中添加一条配置信息 < load-on-startup>5< /load-on-startup>,当值为0或者大于0时,表示容器在应用启动时就加载这个servlet,当是一个负数时或者没有指定时,则指示容器在该servlet被请求时才加载。  

  • Servlet 调用 service() 方法来处理客户端的请求。
void service(ServletRequest,ServletResponse)

  servlet的处理请求方法,在servle被请求时,会被马上调用,每处理一次请求,就会被调用一次。ServletRequest类为请求类,ServletResponse类为响应类

  • Servlet 通过调用 destroy() 方法终止(结束)。
void destory()
  • 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

  2、Filter

  2.1 filter简介  

  filer是javaweb中的过滤器,它与servlet一样,也有三个生命周期方法,同时在web.xml的配置也差不多.但是两者的主要功能不同,servlet负责处理请求,filter负责拦截请求和放行.可以实现Url级别的权限访问,敏感词汇过滤,解决编码问题等等. 

  2.2 filter实现原理

  Filter接口中有一个doFilter方法,当我们编写好Filter,并配置对哪个web资源进行拦截后,WEB服务器每次在调用web资源的service方法之前,都会先调用一下filter的doFilter方法,因此,在该方法内编写代码可达到如下目的:

  1. 调用目标资源之前,让一段代码执行。
  2. 是否调用目标资源(即是否让用户访问web资源)。
  3. 调用目标资源之后,让一段代码执行。

  web服务器在调用doFilter方法时,会传递一个filterChain对象进来,filterChain对象是filter接口中最重要的一个对象,它也提供了一个doFilter方法,我们可以根据需求决定是否调用此方法,调用该方法,则web服务器就会调用web资源的service方法,即web资源就会被访问,否则web资源不会被访问。

  2.3 filter实现步骤

  1. 编写java类实现Filter接口,并实现其doFilter方法。
  2. 在 web.xml 文件中使用<filter>和<filter-mapping>元素对编写的filter类进行注册,并设置它所能拦截的资源。

  范例

package com.test.web.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class FilterDemo01 implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("----过滤器初始化----");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        
        //对request和response进行一些预处理
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        
        System.out.println("Filter执行前");
        chain.doFilter(request, response);  //放行
        System.out.println("Filter执行后");
    }

    @Override
    public void destroy() {
        System.out.println("----过滤器销毁----");
    }
}

  重要的一步,在web.xml中配置拦截规则

<?xml version="1.0" encoding="UTF-8"?>
  <!--配置过滤器-->
  <filter>
      <filter-name>FilterDemo01</filter-name>
      <filter-class>me.gacl.web.filter.FilterDemo01</filter-class>
  </filter>
  
  <!--映射过滤器-->
  <filter-mapping>
      <filter-name>FilterDemo01</filter-name>
      <!--“/*”表示拦截所有的请求 -->
      <url-pattern>/*</url-pattern>
  </filter-mapping>
  
</web-app>

  2.4 filter的四种拦截方式

  REQUEST:直接访问目标资源时执行过滤器。包括:在地址栏中直接访问、表单提交、超链接、重定向,只要在地址栏中可以看到目标资源的路径,就是REQUEST;

      FORWARD:转发访问执行过滤器。包括RequestDispatcher#forward()方法、<jsp:forward>标签都是转发访问;

      INCLUDE:包含访问执行过滤器。包括RequestDispatcher#include()方法、<jsp:include>标签都是包含访问;

      ERROR:当目标资源在web.xml中配置为<error-page>中时,出现异常后,转发到目标资源时,会执行过滤器。

  3、Listener(主要是javaWeb中的监听器)

   3.1 监听器简介

  监听器就是一个实现了特定接口的java类,这个java类用来监听另外一个java类的方法调用或者属性改变,当被监听的对象发生上述事件后,监听器的某个方法就会立即执行.这里就涉及几个相关概念:

  事件源:被监听的对象

  事件:就是事件源的改变,一旦发生变化,事件就会传递给监听器对象,监听器的对应方法就会执行  

  监听器:监听的对象

  绑定监听器:在事件上绑定监听器

  3.2监听器的分类

    在servlet的规范中定义了多种类型的监听器,主要用来监听ServletContext,HttpSession,ServletReques三个域对象.按照功能划分,可以分成三类:

  • 一类:监听三个域对象的创建和销毁的监听器
  • 二类:监听三个域对象的属性变更的监听器(xxxAttribute())
  • 三类:监听HttpSession对象中的JavaBean的状态的改变.(绑定,解除绑定,钝化,活化)       

 三、拓展

  1、servlet是不是单例设计模式?

  servlet并不是单例设计模式,如果有多个Url映射到同一个servlet时,就会出现多个实例.

虽然 Servlet 在多数情况下只有一个实例。但它并不是单例设计模式,即不是真正的单例。  

  2、serlvet线程安全问题?

   基于 JVM 对多线程的支持,这样可以提高代码的执行效率。 不需要为每一个请求都要单独创建/销毁 Servlet(执行 init(), desdroy() )。 
同一段代码可以在同一时间被多个请求同时执行。 Servlet 是普通的 Java 类,因此没有对其做线程安全的处理