JavaWeb三大组件之Filter

JavaWeb有三大组件,Servlet、Listener、Filter。本文将介绍Filter,主要从用处、种类、使用方法等进行介绍。

一、用处

Filter可以认为是Servlet的一种“加强版”。使用Filter完整的流程是:Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。

Filter有以下几个用处:

  • 在HttpServletRequest到达Servlet之前,拦截客户的HttpServletRequest;
  • 根据需要检查HttpServletRequest,也可以修改HttpServletRequest头和数据;
  • 在HttpServletResponse到达客户端之前,拦截HttpServletResponse;
  • 根据需要检查HttpServletResponse,也可以修改HttpServletResponse头和数据。

二、种类

  • 用户授权的Filter:Filter负责检查用户请求,根据请求过滤用户非法请求(比如对用户登录状态进行判定);
  • 日志Filter:详细记录某些特殊的用户请求;
  • 负责解码的Filter:包括对非标准编码的请求解码;
  • 能改变XML内容的XSLT Filter等;
  • Filter可负责拦截多个请求或响应;一个请求或响应也可被多个Filter拦截。

三、使用方法

3.1 创建Filter步骤

1)创建Filter处理类;
2)web.xml文件中配置Filter,或通过注解的方式配置。(顺便说一下,三大组件都需要在web.xml中进行配置)

3.2 创建Filter类

创建Filter类必须实现Filter接口,Filter接口中包含三个方法:

  • void init(FilterConfig config):用于完成Filter的初始化;
  • void destroy():用于Filter销毁前,完成某些资源的回收;
  • void doFilter(ServletRequest srq, ServletResponse srp, FilterChain chain):实现过滤功能,该方法就是对每个请求及响应增加的额外处理。

doFilter()方法,在该方法中可实现对用户请求进行预处理,也可实现对服务器响应进行后处理,分界线就是是否调用了chain.doFiler(),调用之前是请求预处理,调用之后是响应后处理。这是因为,web服务器会检查FilterChain对象中是否还有Filter,如果有,则调用下一个Filter,没有,则调用目标资源。

3.3 配置Filter

与配置Servlet相似,配置Filter,需要配置两个部分:
1)配置Filter名;
2)配置Filter拦截URL模式
与Servlet的区别在于:Servlet通常只配置一个URL,而Filter可以同时拦截多个请求的URL。因此,在配置Filter的URL模式时通常会使用模式字符串,使得Filter可以拦截多个请求。配置的方式有两种:在Filter类中通过注解进行配置,在web.xml文件中进行配置。

3.3.1 注解配置

使用@WebFilter注解进行配置,并添加属性。常用属性如下:

属性 是否必需 说明
asynSupported 指定该Filter是否支持异步操作模式。
dispatcherTypes 指定该Filter仅对那种dispatcher模式的请求进行过滤。该属性支持ASTNC、ERROR、FORWARD、INCLUDE、REQUEST这五个值的任意组合。默认值是同时过滤5种模式的请求。
displayName 指定该Filter的显示名
filterName 指定该Filter的名称
initParams 用于为该Filter配置参数
servletNames 该属性值可指定多个Servlet的名称,用于指定该Filter仅对这几个Servlet执行过滤。
urlPatterns/value 这两个属性的作用完全相同。都指定该Filter所拦截的URL。

3.3.2 web.xml中进行配置

<!-- 定义Filter -->
    <filter>
        <filter-name>log</filter-name>
        <filter-class>filter.LogFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>log</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

Filter里doFilter()方法里的代码就是从多个Servlet的service()方法里抽出的通用代码。通过使用Filter可以实现更好的代码复用。


Filter作用图.png

Filter和Servlet具有完全相同的生命周期行为,且Filter也可以通过<init-param.../>元素或@WebFilter的initParams属性来配置初始化参数,获取Filter的初始化参数则使用FilterConfig的getInitParameter()方法。

四、举个栗子

/**
 * AuthorityFilter.java
 */

@WebFilter(filterName = "authority", urlPatterns = {"/*"}, initParams = {
        @WebInitParam(name = "encoding",value = "UTF-8"),
        @WebInitParam(name = "loginPage",value = "/login.jsp"),
        @WebInitParam(name = "proLogin",value = "proLogin.jsp")
})
public class AuthorityFilter implements Filter{

    private FilterConfig config;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.config = filterConfig;
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        /**
         * 通过config获取初始化参数
         */
        String encoding = this.config.getInitParameter("encoding");
        String loginPage = this.config.getInitParameter("loginPage");
        String proLogin = this.config.getInitParameter("proLogin");
        /**
         * 通过获取到的初始化参数设置解码格式
         */
        servletRequest.setCharacterEncoding(encoding);
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        HttpSession session = httpServletRequest.getSession(true);
        String requestPath = httpServletRequest.getServletPath();
        /**
         * 若用户未登录,并且请求地址不是登录页和处理登录页,跳转到登录页;
         * 若登录了,则调用filterChain.doFilter()返回资源。
         */
        if (session.getAttribute("user")==null
                && !requestPath.endsWith(loginPage)
                && !requestPath.endsWith(proLogin))
        {
            httpServletRequest.setAttribute("tip","您还没有登录");
            httpServletRequest.getRequestDispatcher(loginPage).forward(httpServletRequest,servletResponse);
        } else {
            filterChain.doFilter(httpServletRequest,servletResponse);
        }
    }

    @Override
    public void destroy() {
        this.config = null;
    }
}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容

  • 本文包括:1、Filter简介2、Filter是如何实现拦截的?3、Filter开发入门4、Filter的生命周期...
    廖少少阅读 7,235评论 3 56
  • Spring Web MVC Spring Web MVC 是包含在 Spring 框架中的 Web 框架,建立于...
    Hsinwong阅读 22,264评论 1 92
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,566评论 18 139
  • IOC 控制反转容器控制程序对象之间的关系,而不是传统实现中,有程序代码之间控制,又名依赖注入。All 类的创建,...
    irckwk1阅读 922评论 0 0
  • 很多人,尤其是步入中年的女士,平常很少锻炼身体,手臂上堆积了厚厚的脂肪,手臂一动,脂肪就变成天然的“蝴蝶袖”。 为...
    一颗梧桐树阅读 3,427评论 0 9