动态注册之Servlet+Filter+Listener

Java Web中的Servlet+Filter+Listener注册方式


  • xml文件注册

  • 注解注册(Servlet 3.0 +)

  • ServletContext 动态注册


Xml文件注册

  • Servlet
  <servlet>
        <servlet-name>partServlet</servlet-name>
        <servlet-class>servlet.asyn.PartServlet</servlet-class>
        <async-supported>false</async-supported>
        <multipart-config>
            <location>D:\\project\\servlet-asyn\\target\\servlet-asyn\\upload</location>
        </multipart-config>
        <load-on-startup>0</load-on-startup>
        <init-param>
            <param-name>db</param-name>
            <param-value>mysql</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>partServlet</servlet-name>
        <url-pattern>/ps</url-pattern>
    </servlet-mapping>

async-supported 表示用户对Servlet的请求是否为异步处理
multipart-config 表示servlet接收文件上传时的配置,location子元素表示文件上传的位置
load-on-startUp 表示servlet在何时初始化,Web容器启动时初始化,还是用户请求某个Servlet时对其初始化

Servlet_xml.png
  • Filter
<filter>
        <filter-name>EncodingFilter</filter-name>
        <filter-class>filter.EncodingFilter</filter-class>
        <async-supported>false</async-supported>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>EncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>

filter 拦截资源是按照 filter-mapping 配置节出现的顺序来依次调用 doFilter() 方法的
async-supported 表示用户对Filter的请求是否为异步
dispatcher 表示在过滤用户的请求时,过滤什么类型的请求?Forward,Request,Include,Error,Async

Filter_xml.png
  • Listener
<listener>
        <listener-class>listener.CustomServletContextListener</listener-class>
    </listener>
Listener_xml.png

注解注册(Servlet3.0+)

  • Servlet
@MultipartConfig(location = "D:\\project\\servlet-asyn\\target\\servlet-asyn\\upload")
@WebServlet(asyncSupported = false,
        urlPatterns = {"/ps"},
        loadOnStartup = 0,
        name = "PartServlet",
        initParams = {@WebInitParam(name="db",value="mysql")}
)

对比上述的注解配置,便可将xml配置的所有键值转化成注解的形式。

Servlet_annotation.png

如上述代码:
若想获取文件上传的配置MultipartConfig注解的location属性,即上传文件的存放位置。则在程序中,应该使用反射获取注解的location属性值。

String locationFile = this.getClass().getAnnotation(MultipartConfig.class).location()
  • Filter
@WebFilter(urlPatterns = {"/*"},
        dispatcherTypes = {DispatcherType.REQUEST},
        asyncSupported = false,
        initParams = {@WebInitParam(name="encoding",value="utf-8")}
)

对比上述的注解配置,便可将xml配置的所有键值转化成注解的形式。

Filter_annotation.png

在使用Filter的时候,一定要注意Filter的顺序,在注解中,Filter的过滤顺序是按照过滤器的Class名称的首字母进行排序,而进行过滤

  • Listener
    Listener_annotation.png

ServletContext 动态注册

Servlet,Listener,Filter由ServletContext去加载,无论是使用xml配置还是使用Annotation注解配置,均由Web容器进行初始化,读取其中的配置属性,然后向Web容器中进行注册。Servlet 3.0 可以由ServletContext动态进行注册,因此需在Web容器初始化的时候(即建立ServletContext对象的时候)进行动态注册。

  • 自定义ServletContextListener
  • 改写其方法contextInitialized,在该方法中动态注册Servlet,Filter,Listener

  • Servlet
    需要配置Servlet的参数为:loadOnStartup,urlMapping,initParameter,asyncSupport,MultipartConfig等。

    Servlet_Dynamic.png

在配置文件上传的属性时注意:

Multipart_Dynamic.png

在Servlet或者其他的业务组件中,要想获取文件的上传路径location属性,则可以在其动态注册的时候,将其放在ServletContext对象中。因此在接下的Web容器响应和请求中,只有容器开启,就可以从ServletContext中获取到改属性值。
xml中配置:

<multipart-config>
            <location>/tmp</location>
            <file-size-threshold>10</file-size-threshold>
            <max-file-size>10</max-file-size>
            <max-request-size>10</max-request-size>
</multipart-config>

注解配置:

@MultipartConfig(location = "/tmp",maxFileSize = 10,maxRequestSize = 10,fileSizeThreshold = 1024)

动态注册配置:


Multipart_config.png

这三者配置的原理是一样的,动态注册配置中,要想读取上传文件的location属性值,则在动态注册时候将该location值写入ServletContext上下文对象中,然后在Servlet再次进行读取。

location 将上传文件写入服务器的绝对路径
maxFileSize 允许上传单个文件的最大值,默认为-1,则表示没有限制
maxRequestFileSize 当有多个文件进行上传时,该值表示所有上传文件总的最大值。

  • Filter
    Filter_dynamic.png

对Filter过滤顺序需要注意的是:
1、xml中Filter过滤顺序由Filter配置的节点顺序决定。
2、Annotation中Filter过滤顺序由Filter的类名决定的,根据类名进行排序。
3、动态注册Filter中,过滤顺序由isMatchAfter属性决定。

Filter_Sort.png

该方法有三个参数:
1、EnumSet<DispatcherType> dispatcherTypes 表示过滤器拦截的类型 Forward,Include,Request,Error,Async
2、boolean isMatchAfter 表示该过滤器是够放在当前web应用中已经存在的过滤器之后,true表示放在当前应用所有的过滤器之后,false表示将该过滤器放在当前应用所有的过滤器之前
3、String... urlPatterns 表示拦截的url

  • Listener
    Listener_dynamic.png

推荐阅读更多精彩内容

  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 44,325评论 6 344
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 131,256评论 18 138
  • 本文包括:1、Filter简介2、Filter是如何实现拦截的?3、Filter开发入门4、Filter的生命周期...
    廖少少阅读 6,773评论 3 56
  • Servlet 3.0 新特性概述 Servlet 3.0 作为 Java EE 6 规范体系中一员,随着 Jav...
    lovePython阅读 455评论 0 5
  • 本章聊一聊ServletContext 3.0规范中定义的注解以及在web应用中使用的框架和库的可插拔性的提升。 ...
    Lucky_Micky阅读 5,484评论 0 3
  • 通过LDAP权限配置可以实现对cognos文件夹和报表的权限管理。这里主要是结合数据库的数据模型和cognos的过...
    夏无忧阳阅读 1,069评论 0 0
  • 此时在字节码生成的Country2类是final类,并且没有无参的构造方法。如果需要当作JavaBean使用,需要...
    lkmc2阅读 560评论 0 0
  • 我是很不会写文章的,语句不通顺、叙事逻辑不通、划分段落也不会,不过这些都没有关系,我又不指望我能拿个诺贝尔文学奖,...
    张和生阅读 43评论 0 0
  • 忽忽悠悠的已经开学半个多月了,一边看着银行卡里的钱感叹着时间过得真慢啊,一边又看着什么都不会的课本希望时间慢一点啊...
    这是小花啊阅读 156评论 0 0
  • 看到简书上有一个活动:给闺蜜的六行情书。想到了黄大壮。想起她曾经发过一首小诗给我,诗里有一句,“你是船,我是树”。...
    糖稀阅读 869评论 14 23