Java Web - 服务器中的过滤器和监听器

一 过滤器

每个servlet都有自己需要处理的资源,这么多的资源我们有时候我们希望统一的进行管理,比如对响应的图片进行加水印处理,对提交和响应的数据的编码进行统一,或者是对提交的数据进行过滤。

解决的办法就是使用过滤器,他的目的是对服务器和浏览器之间交互的资源进行管理和保护servlet安全(一定程度上)。他的角色就像是服务器与浏览器之间的桥梁。它是由服务器调用执行的。

1.1 使用过滤器

1. 实现Filter接口
2. 覆写接口方法

public class MyFilter implements Filter {
	//启动即执行,进行资源初始化
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("MyFilterinit!!");
    }
    
	//请求发送执行,进行资源管理
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    	System.out.println("MyFilteredoFilterExit!!");
        //放行,这里如果不放行,请求就不会被servlet处理
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("MyFilterdoFilterReturn!!");
    }

	//服务器关闭执行,对资源进行关闭
    @Override
    public void destroy() {
        System.out.println("MyFilterdestroy!!");
    }
}

3. 在web.xml中配置过滤器

<filter>
    <filter-name>myFilter</filter-name>
    <filter-class>com.chester.web.servlet.MyFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>myFilter</filter-name>
    <!--/*代表对所有项目根目录的请求都过滤-->
    <url-pattern>/*</url-pattern>
</filter-mapping>

这里的 <url-pattern>有很灵活的写法,根据项目需求来写即可,这里再给出几个例子

<!--拦截所有以.do结尾的请求,一般进行的是模块拦截-->
<url-pattern>*.do</url-pattern>
<!--拦截指定url请求,针对某个servlet的请求进行拦截,保护servlet-->
<url-pattern>/ts</url-pattern>

在执行一个过滤器之后,如果还有符合要求的过滤器,则再执行符合要求的过滤器,执行完doFilter方法中filterChain.doFilter()方法后,继续执行doFilter中接下来的代码。

1.2 案例

下面我们来看看几个具体的使用场景,我们只关注关键代码部分。代码设置了接收和发送的编码格式,以及实现对session的管理,如果session失效,则要求用户重新登陆。

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
   //编码格式设置
   servletRequest.setCharacterEncoding("utf-8");
   servletResponse.setContentType("text/html;charset=utf-8");
   //session管理,
   HttpSession hs = ((HttpServletRequest)servletRequest).getSession();
   if(hs.getAttribute("user") == null){
       ((HttpServletResponse)servletResponse).sendRedirect("/JavaWebTest/login.jsp");
   }else{
       //放行
       filterChain.doFilter(servletRequest, servletResponse);
   }
}

二 监听器

上面我们使用了过滤器对资源进行统一的管理,但是有的时候,我们需要知道数据流转的具体过程,比如作用域对象是什么时候创建和销毁的,作用域对象中的数据是什么时候存取,改变和删除的。以此来进行一些处理,比如如果统计网站的在线人数,我们就需要知道session是什么时候销毁和创建的。创建在线人数+1,销毁则-1。通过监听器就可以完成这样的功能。

2.1 使用监听器

监听器可以监听request、session、application的创建销毁和内容的改变,下面

2.1.1 监听request对象

创建ServletRequestListener的实现类

public class MyListener implements ServletRequestListener, ServletRequestAttributeListener{
    //监听作用域创建于销毁 继承 ServletRequestListener
    //作用域销毁时调用
    public void requestDestroyed(ServletRequestEvent sre) {
        sre.getServletRequest();
        System.out.println("MyListenerDestroyed");
    }

    //作用域创建时调用
    public void requestInitialized(ServletRequestEvent sre) {
        System.out.println("MyListenerInitialized");
    }

    //监听作用域数据修改 继承 ServletRequestAttributeListener
    //数据增加时调用
    public void attributeAdded(ServletRequestAttributeEvent srae) {
        System.out.println("request 中增加了-" + srae.getName() + ":" +srae.getValue());
    }

    //数据删除时调用
    public void attributeRemoved(ServletRequestAttributeEvent srae) {
        System.out.println("request 中删除了-" + srae.getName() + ":" +srae.getValue());
    }

    //数据修改时调用
    public void attributeReplaced(ServletRequestAttributeEvent srae) {
        System.out.println("request 中改变了-" + srae.getName() + ":" +srae.getValue());
    }
}

在web.xml中配置监听器

<!--配置监听器-->
<listener>
    <listener-class>com.chester.web.servlet.MyListener</listener-class>
</listener>
2.1.2 监听session对象

和request一样,继承HttpSessionListener,HttpSessionAttributeListener

2.1.3 监听application对象

一样,继承ServletContextListener, ServletContextAttributeListener

2.2 监听器使用案例

该案例在application对象中使用count这个键维护网站的登陆人数,你可以在适当的地方进行取用。

public class MyListener implements  HttpSessionListener, ServletContextListener{
    //当一个session建立的时候,说明有用户进行了登陆count++
    public void sessionCreated(HttpSessionEvent se) {
        ServletContext sc = se.getSession().getServletContext();
        int count = (int)sc.getAttribute("count");
        sc.setAttribute("count", ++count);
    }

    //当一个session销毁的时候,说明有用户进行了退出count--
    public void sessionDestroyed(HttpSessionEvent se) {
        ServletContext sc = se.getSession().getServletContext();
        int count = (int)sc.getAttribute("count");
        sc.setAttribute("count", --count);
    }

    //application对象建立时,初始化count为0
    public void contextInitialized(ServletContextEvent sce) {
        //获取application
        ServletContext sc = sce.getServletContext();
        sc.setAttribute("count", 0);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值