9.3 Servlet中的Listener&Filter

前言

这几章都比较枯燥哈,要耐心一点,配置这些也很重要&有必要(相比于业务处理)。

万一出了什么幺蛾子,同时你知道了是配置、初始化的问题,就可以从学的这些入手来Debug了。

Servlet 中的 Listener(监听器)

基础知识

设计模式——观察者模式设计中,最容易理解和体现的恐怕就属Listener了(监听器),Tomcat服务器中这个概念用的很广泛。(某些憨憨别把Listener当接口或者类来看了)

Servlet中的 Listener ,能够让Servlet很方便地从另一个角度,去控制程序和数据。

在Tomcat服务器中,具体设计的Listener有:

  • Listener:
    • EventListeners(有关事件)
      • ServletContextAttributeListener
      • ServletRequestAttributeListener
      • ServletRequestListener
      • HttpSessionAttributeListener
    • LifecycleListeners(有关生命周期)
      • ServletContextListener
      • HttpSessionListener

具体区别嘛,来人,上图:

在这里插入图片描述

具体有哪些接口和接口的说明,请在需要的时候自行查表。(就不浪费篇幅了,重在理解)

这些 Listener 的实现类可以配置在 web.xml 中的 标签中。

(当然也可以在应用程序中自己动态地添加 Listener,一般都这样做了)

需要注意的是 ServletContextListener(第二类第二个) 在容器启动之后就不能再添加新的,因为它所监听的事件已经不会再出现。

事例

如同在Spring框架中,ContextLoaderListener (org.springframework.web.context.ContextLoaderListener) 就实现了一个ServletContextListener。

当启动容器,进行加载时,ContextLoaderListener 类就会在contextInitialized()方法中初始化Spring容器 :

public void contextInitialized(ServletContextEvent event){
    this.contextLoader = createContextLoader();
    if(this.contextLoader == null){
        this.contextLoader = this;
    }
    this.contextLoader.initWebApplicationContext(event.getServletContext());
}

Spring加载容器有两种(我知道的):

  • 通过web.xml的标签中配置的applicationContext.xml的路径找到该文件。
  • /WEB_INF/路径下查找默认的applicationContext.xml文件。

Servlet 中的 Filter(过滤器)

Filter用起来是最爽的了,可以通过和组合来使用。

其实啊,Filter可以完成和Servlet同样的工作(可以看做Servlet的变种),而且更灵活——它比Servlet多提供了一个FilterChain对象,来帮我们控制请求(xxxresponse)的流转(也就是一种预处理)。

总体性地说,Filterd的作用:对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。

基础知识

  1. Filter用处:

    • 在HttpServletRequest到达Servlet之前,拦截客户的HttpServletRequest。

    • 根据需要检查HttpServletRequest,也可以修改HttpServletRequest头和数据。(HttpServletResponse同理)

  2. Filter种类:

    • 用户授权的Filter:Filter负责检查用户请求,根据请求过滤用户非法请求。
    • 日志Filter:详细记录某些特殊的用户请求。
    • 负责解码的Filter:包括对非标准编码的请求解码

    另外,一个Filter可拦截多个请求或响应;一个请求或响应也可被多个拦截

  3. Filter的实现类

    FilterConfig和FilterChain的具体实现类是ApplicationFilterConfig 和 ApplicationFilterChain。

    但是,Filter的实现类是由用户自定义的,实现接口就行。(其中ApplicationFilterChain类将多个Filter串联起来,组成一个链)

    Filter中重要的三个接口方法

    • init(FilterConfig):

      初始化的时候调用该方法,可以写一些环境变量配置等的获取操作

    • doFilter(ServletRequest, ServletResponse, FilterChain):

      核心功能,正如上面的**“总结”**所言,就不多说了,提一点:

      • 调用FilterChain.doFilter()传递请求,到下一个Filter中去处理
      • 不调用的话,请求就直接返回了。
    • destroy():

      销毁时调用,而且Web容器会再次嗲用doFilter()方法!

  4. Filter执行流程:

    Filter的核心实际上还是FilterChain对象,这个对象保存了最终的Servlet和所以Filter对象(保存在了filters[]数组中),下面是执行的时序图:
    然后 = =,CSDN有点毒瘤,mermaid给我砍了,下面的类分别是 :

    • StandarWapperValue
    • ApplicationFilterFactory
    • ApplicationFilterChain
    • Filter
    • Servlet
    StandarWa ApplicationF Application Filter Servlet 1.单例模式获取factory对象 2.creatFilterChain() ApplicationFilterChain获取web. cml中的对应的Filter,放在filters[]数组 3.doFilter() 4.获取filters[]数组中的第一个Filter 获取的实际上是fil terConfig对象 5.doFilter() 6.service()方法 StandarWa ApplicationF Application Filter Servlet

事例

这是一个用来解决全站中文乱码问题的过滤器【开发过程中写的,不是框架自带的】:(具体编解码知识请到3.x学习)

public class CharacterEncodingFilter implements Filter {
 
     private FilterConfig filterConfig = null;
     //设置默认的字符编码
     private String defaultCharset = "UTF-8";
 
     public void doFilter(ServletRequest req, ServletResponse resp,
             FilterChain chain) throws IOException, ServletException {
         
         HttpServletRequest request = (HttpServletRequest) req;
         HttpServletResponse response = (HttpServletResponse) resp;
         String charset = filterConfig.getInitParameter("charset");
         if(charset==null){
             charset = defaultCharset;
         }
         request.setCharacterEncoding(charset);
         response.setCharacterEncoding(charset);
         response.setContentType("text/html;charset="+charset);
         
         MyCharacterEncodingRequest requestWrapper = new MyCharacterEncodingRequest(request);
         chain.doFilter(requestWrapper, response);
     }
 
     public void init(FilterConfig filterConfig) throws ServletException {
         //得到过滤器的初始化配置信息
         this.filterConfig = filterConfig;
     }
     
     public void destroy() {
 
     }
 }

章节总结

第九章从:

  • Servlet容器的启动
  • Servlet初始化细节
  • Servlet体系结构

来描绘一个粗略的结构图,方面后面的讲解和理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值