Filter,Listener

Filter基本使用

过滤器Filter作为Web的组件,能对所有Web资源(Jsp,Servlet,,静态图片或静态HTML文件等),进行过滤拦截。

1.编写java类实现Filter接口,并实现其doFilter方法。
class FilterDemo implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //过滤器初始化
    }

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

        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;

        //让过滤器放行
        //过滤器相互之间是不清楚它的上一个或下一个是谁,所有的调用都是服务器在处理
        //Filter执行顺序可以由<filter_mapping>的顺序决定
        filterChain.doFilter(req, resp);
    }

    @Override
    public void destroy() {
        //过滤器销毁
    }
}
2.web.xml中配置Filter
<?xml version="1.0" encoding="UTF-8"?>
<web-app >

    <filter>
        <filter-name>FilterDemo</filter-name>
        <filter-class>com.filter.FilterDemo</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>FilterDemo</filter-name>

        <!-- 指过滤哪些资源  /*拦截所有 -->
        <url-pattern>/hello</url-pattern>

        <!-- 如果请求转发需要如下配置 -->
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>

</web-app>


Filter配置细节
1.一个Filter可以有多个<url-pattern>,可以对多个资源进行过滤。
2.Filter默认只是对一次正常的请求(在地址栏中请求一次)做拦截。
3.File可以用反射配置
Filter配置细节
  • REQUEST
    默认配置,如果目标资源是通过RequestDispatcher的include()或forward()访问时,那么该过滤器就不会被调用。

  • INCLUDE
    如果目标资源是通过RequestDispatcher的include()访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。

  • FORWARD
    如果目标资源是通过RequestDispatcher的forward()访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。

  • ERROR
    如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。

Filter链
  • 在web应用中,可以存在多个Filter,这些Filter组合起来即为一个Filter链。

  • web服务器根据Filter在web.xml文件中的注册顺序,决定先调用哪个Filter。

  • 当第一个Filter的doFilter()被调用时,web服务器会创建一个代表Filter链的FilterChain对象传递给该方法,web服务器会检查FilterChain对象中是否还有Filter,如果有,则调用第2个Filter,如果没有,则调用目标资源。


Listener

Listener用于监听Web应用中的某些信息(对象或信息的增删改),然后作出相应的响应处理。

1.ServletContextListener
用于监听Web应用的启动与关闭

@WebListener
public class MyContextListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        //应用开启时调用
        String switchUserName = sce.getServletContext()
                .getInitParameter("switch_user_name");

        System.out.println("打开应用的用户:" + switchUserName);
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        //应用关闭时调用
        sce.getServletContext().getRealPath("img");
    }
}
在web.xml中配置Listerner
<web-app>

    <listener>
        <listener-class>com.listener.MyContextListener</listener-class>
    </listener>
</web-app>

在Servlet3.0中,Listener可以直接在代码中通过注解来完成,无需在web.xml中配置。

@WebListener //表明以下是个监听器
public class MyContextListener implements ServletContextListener {

}
2.ServletContextAttributeListener
用于监听ServletContext范围(application)内属性的改变。

@WebListener
public class MyListener implements ServletContextAttributeListener {

    @Override
    public void attributeAdded(ServletContextAttributeEvent scae) {
        String name = scae.getName();
        Object value = scae.getValue();
        System.out.println("属性名:" + name + "," + "属性值为:" + value);
    }

    @Override
    public void attributeRemoved(ServletContextAttributeEvent scae) {

    }

    @Override
    public void attributeReplaced(ServletContextAttributeEvent scae) {
        //替换时触发
    }
}


public class ReviewServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        String user = req.getParameter("user");

        //向Application添加属性,即触发Listener
        getServletContext().setAttribute("Demo", new User(user, 1));
    }
}

输出结果
属性名:Demo,属性值为:User{name='Test', age=1}
3.ServletRequestListener,ServletRequestAttributeListener
ServletRequestListener:用于监听用户请求

ServletRequestAttributeListener:用于监听request范围内属性的变化


@WebListener
public class MyListener implements ServletRequestListener,
        ServletRequestAttributeListener {


    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        //用户请求到达时触发
        HttpServletRequest servletRequest = 
                (HttpServletRequest) sre.getServletRequest();
        
        String ip = servletRequest.getRemoteAddr();
        String requestURI = servletRequest.getRequestURI();;

        System.out.println("IP:" + ip + "请求的资源:" + requestURI);
    }

    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
        //用户请求结束后触发
    }

    @Override
    public void attributeAdded(ServletRequestAttributeEvent srae) {
        String name = srae.getName();
        Object value = srae.getValue();
        System.out.println("Name:" + name + "," + value.toString());
    }

    @Override
    public void attributeRemoved(ServletRequestAttributeEvent srae) {

    }

    @Override
    public void attributeReplaced(ServletRequestAttributeEvent srae) {

    }
}


public class ReviewServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        String user = req.getParameter("user");

        req.setAttribute("Demo",user);
    }
}
4.HttpSessionListener,HttpSessionAttributeListener
HttpSessionListener:用于监听用户session开始与结束

HttpSessionAttributeListener:用于监听HttpSession属性的增删改


@WebListener
public class MyListener implements HttpSessionListener, 
        HttpSessionAttributeListener {

    @Override
    public void sessionCreated(HttpSessionEvent se) {
        String userName = se.getSession().getAttribute("user").toString();
        String id = se.getSession().getId();
        System.out.println("数据:" + userName + ",会话ID:" + id);
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {

    }

    @Override
    public void attributeAdded(HttpSessionBindingEvent se) {
        String name = se.getName();
        String value = se.getValue().toString();
        System.out.println("Name:" + name + ",Value:" + value);
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent se) {

    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent se) {

    }
}


public class ReviewServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

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

推荐阅读更多精彩内容

  • Filter可以视作是servlet的加强版,主要用作对用户的请求进行预处理,或者对返回给客户端的结果进行再次加工...
    Single_YAM阅读 2,608评论 1 7
  • Filter简介 Filter也称之为过滤器,它是Servlet技术中最实用的技术,Web开发人员通过Filter...
    java部落阅读 278评论 0 1
  • Filter的使用和经典案例 一、什么是Filter Filter也称之为过滤器。 通过Filter可以拦截所有对...
    明天你好向前奔跑阅读 1,120评论 0 5
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,087评论 18 139
  • 创建 编写一个过滤器的类,实现Filter接口 实现接口尚未实现的方法,着重实现doFilter方法 在web.x...
    蕊er阅读 397评论 0 0