zoukankan      html  css  js  c++  java
  • Servlet、Filter、Listener、Interceptor基础

    第一:Servlet

    Servlet是个接口,全限定名是javax.servlet.Servlet,在javax.servlet包中,在servlet-api.jar(在tomcat自带的lib文件夹中)或是在javax.servlet-api-xxx.jar(在maven中引入javax.servlet-api依赖)。

    如果我们用IDE工具,右键new,选择Servlet的方式创建一个Servlet,则会自动继承javax.servlet.http.HttpServlet(HttpServlet类实现了Servlet接口),我们只需定义好Servlet名称、在URL mapping框中填好url pattern的值,如果有需要,还可以在Intialization parameters框中填入初始化参数的值。

    此外,url pattern的值必须以斜杠"/"或者“*.”开头,如果填入的值不满足这个要求,IDE工具就会提示URL patterns should start with "/" or "*."。如果我们在创建好Servlet之后再手动把url pattern的值修改为不满足条件的值,则此项目就不能启动了,启动项目时会弹出Problem Occured错误提示框,提示 ‘Starting Tomcat v7.0 Server at localhost’ has encountered a problem,控制台也会报异常org.apache.catalina.LifecycleException:Caused by: org.apache.catalina.LifecycleException: A child container failed during start。

    Servlet的生命周期:

    1.Servlet实例化

    Servlet实例化有2个时机,第一种是客户端第一次请求时,系统创建对应的Servlet实例,默认是这种;第二种是系统启动后就创建Servlet实例,这种要配置load-on-startup的值,0-5的整数,0表示优先级最高,最快实例化。其实负整数也不会报错,只是不起作用,系统还是在客户端第一次请求时创建对应的Servlet实例。

    2.Servlet初始化

    init(ServletConfig config)方法,如果在创建Servlet类时填写了Intialization parameters,则这些值将被封装在ServletConfig实例中,并传入到init方法中。

    3.Servlet处理客户端请求,service()方法。

    4.Servlet销毁

    系统在关闭前会调用destroy()方法销毁Servlet实例。

    如何获取该servlet的配置参数?

    HttpServlet的父类GenericServlet中有getServletConfig()方法,我们自己建的servlet调用父类此方法就可以得到ServletConfig实例了,然后在调用ServletConfig的实例方法getInitParameter(String name)就可以获得指定的配置参数的值了。

    第二:Filter

    Filter也是个接口,全限定名是javax.servlet.Filter,跟Servlet接口在同一目录下。如果配置了Filter,且请求地址满足Filter的url pattern,则请求在到达对应的Servlet之前会先到达Filter。可以有多个Filter,请求到达这些Filter的顺序是由这些Filter在web.xml文件中<url-pattern>*.action</url-pattern>配置的先后顺序决定的,从上到下匹配,先匹配到哪个Filter,请求就先到哪个Filter。因为请求会在到达Servlet之前先到达Filter,所以可以用Filter对用户请求进行预处理,之后再将请求交给Servlet处理,处理之后,再用Filter对响应进行后处理。

    有2种常见用法:

    1.用户鉴权Filter

    接收到请求之后,看用户是否登录了或者看用户是否有对应的访问权限,如果没有,则提示登录或者提示没有权限,如果没问题,则将请求交给Servlet处理。

    2.处理字符编码的Filter

    设置请求与响应的字符编码为指定格式。

    需要说明的是,Filter是在应用一启动的时候就实例化的,紧接着就初始化,而不像Servlet那样可以在第一次请求的时候再实例化。而且,多个Filter实例化的顺序并不一定按照在web.xml文件中配置的顺序。另外,经过实际测试发现一个现象,客户端发起一个请求,到达Filter,按道理来说应该是Filter处理完,请求到达Servlet后再实例化对应的Servlet,但实际却是只要客户端发了请求,实例化、初始化Filter之后就会实例化、初始化对应的Servlet,这时候请求还没有到达对应的Servlet

    Filter处理请求主要是用doFilter(ServletRequest request, ServletResponse response, FilterChain chain)方法,多个Filter间传递请求、最后一个Filter向Servlet传递请求都是在上述doFilter()方法中调用FilterChain接口的doFilter ( ServletRequest request, ServletResponse response )方法,如果之后再调用入参ServletResponse实例的API,则就是对响应进行后处理了。

    如何获取该filter的配置参数?

    不像获取servlet配置参数一样,没有现成的getFilterConfig()可供调用,但是发现Filter接口的init(FilterConfig filterConfig)方法参数竟然是FilterConfig实例,看来是把初始化参数封装到了此实例当中,如此,我们可以在filter类中创建FilterConfig类型的成员变量,在init方法中把filterConfig赋值给此成员变量,这样就可以在doFilter()方法中调用此FilterConfig类型的成员变量的getInitParameter(xxx)方法获取指定的初始化参数的值了。

    第三:Listener

    Listener接口分为3类:

    1.监听web应用,主要用的是ServletContextListener(javax.servlet.ServletContextListener)接口,web应用的启动与关闭各触发接口的一个方法:

    web应用启动触发contextInitialized(ServletContextEvent sce)方法,web应用关闭触发contextDestroyed(ServletContextEvent sce)方法。

    2.监听session,主要用的是HttpSessionListener(javax.servlet.http.HttpSessionListener)接口,用户session的开始和结束各触发接口的一个方法:

    session开始触发sessionCreated(HttpSessionEvent se)方法,session结束触发sessionDestroyed(HttpSessionEvent se)方法。

    3.监听reqeust,主要用的是ServletRequestListener(javax.servlet.ServletRequestListener)接口,用户发起请求、请求结束时各触发接口的一个方法:

    用户发起请求时触发requestInitialized(ServletRequestEvent sre)方法,请求结束时触发requestDestroyed(ServletRequestEvent sre)方法。

    创建监听类,只需实现对应的xxxListener接口即可。

    综上,系统启动后会先触发ServletContextListener实现类的contextInitialized()方法,再实例化、初始化所有的Filter实现类,再实例化、初始化所有配置了load-on-startup的Servlet,用户发起请求后,先实例化、初始化对应的Servlet,然后符合请求条件的Filter链预处理请求之后传给Servlet处理请求,Filter链再后处理响应,之后将响应结果展示给用户。

    项目中如果用了Spring框架,为了让web应用在启动时就创建IOC容器,需要在web.xml文件中配置一个监听器,监听器类是spring-web-xxx.jar包中的ContextLoaderListener(org.springframework.web.context.ContextLoaderListener,实现了ServletContextListener接口),并且还要为此类配置一个web应用配置参数。

    <!-- 配置监听器ContextLoaderListener -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <!-- 参数名必须是contextConfigLocation -->
        <param-name>contextConfigLocation</param-name>
        <!-- 参数值是配置文件的名字 -->
        <param-value>classpath:applicationContext*.xml</param-value>
    </context-param>

    第四:Interceptor

    Interceptor,拦截器,在spring mvc框架中也有较多的应用。

    在spring-webmvc-xxx.jar中有一个HandlerInterceptor接口,有一个常用的实现类HandlerInterceptorAdapter,我们既可以直接实现HandlerInterceptor接口也可以继承HandlerInterceptorAdapter类,不论是实现接口还是继承实现类,都需要重写里面的几个方法(preHandle、postHandle、afterCompletion方法),来实现自己的需求。

    除了HandlerInterceptor接口外,在spring-web-xxx.jar包中还有一个WebRequestInterceptor接口,该接口及其实现类WebRequestHandlerInterceptorAdapter也是可以用的。

  • 相关阅读:
    Centos7
    appium+python常见报错(appium方面)
    python标准库之datetime
    python异常捕获
    python写入文件和读取文件
    python标准库之collections
    python导入类
    python3+robotframework+pycharm安装运行
    python 继承/父类和子类的关系
    python_类
  • 原文地址:https://www.cnblogs.com/koushr/p/5873378.html
Copyright © 2011-2022 走看看