.Net转Java自学之路—基础巩固篇三十一(Listener、Filter)

监听器:

  监听三大组件:Servlet、Listener、Filter。

  三大组件都需要在web.xml中进行配置。Listener中由二个感知监听器不需要配置。

  Listener:

    特性:

      1、是一个接口,内容自定义来实现。

      2、需要注册。在web.xml中进行配置

      3、监听器的方法,会在特殊事件发生时被调用。

    监听器监听的是事件源。

    JavaWeb中的监听器:

      JavaWeb中监听的事件源为三大域:ServletContext、HttpSession、ServletRequest

      三大域同有俩种监听方式:

        生命周期监听:

          ServletContextListener、HttpSessionListener、ServletRequestListener 他们有俩个方法。一个在服务器启动时调用,一个在服务器关闭时调用。

//ServletContext:
    void contextInitialized(ServletContextEvent se){}//创建ServletContext时
    void contextDestroyed(ServletContextEvent se){}//销毁ServletContext时
//HttpSession:
    void sessionCreated(HttpSessionEvent se){}//创建session时
    void sessionDestroyed(HttpSessionEvent se){}//销毁session时。
//ServletRequest:
    void requestInitialized(ServletRequestEvent se){}//创建ServletRequest时
    void requestDestroyed(ServletRequestEvent se){}//销毁ServletRequest时

        属性监听:

          ServletContextAttributeListener、HttpSessionAttributeListener、ServletRequestAttributeListener它们都有三个方法,一个在添加属性时调用,一个在替换属性时调用,最后一个在移除属性时调用。

//ServletContext:
    void attributeAdded(ServletContextAttributeEvent event){}//添加属性时
    void attributeReplaced(ServletContextAttributeEvent event){}//替换属性时
    void attributeRemoved(ServletContextAttributeEvent event){}//移除属性时
//HttpSession:
    void attributeAdded(HttpSessionBindingEvent event){}//添加属性时
    void attributeReplaced(HttpSessionBindingEvent event){}//替换属性时
    void attributeRemoved(HttpSessionBindingEvent event){}//移除属性时
//ServletRequest:
    void attributeAdded(ServletRequestAttributeEvent event){}//添加属性时
    void attributeReplaced(ServletRequestAttributeEvent event){}//替换属性时
    void attributeRemoved(ServletRequestAttributeEvent event){}//移除属性时

      书写监听器时,必须实现某个监听器接口,并在web.xml中配置。

      事件对象:

//ServletContextEvent:
    ServletContext getServletContext();
    //ServletContextAttributeEvent:
        ServletContext getServletContext();
        String getName();//获取属性名
        Object getValue();//获取属性值

//HttpSessionEvent:
    HttpSession getSession();
    //HttpSessionBindingEvent:
        HttpSession getSession();
        String getName();//获取属性名
        Object getValue();//获取属性值

//ServletRequestEvent:
    ServletRequest getServletRequest();
    ServletContext getServletContext();
    //ServletRequestAttributeEvent:
        ServletRequest getServletRequest();
        String getName();//获取属性名
        Object getValue();//获取属性值

      web.xml配置

<listener>
    <listener-class></listener-class>
</listener>

      感知监听:

        它是用来添加到JavaBean上,而不是添加到三大域上。都与HttpSession相关。这俩个监听器都不需要在web.xml中配置注册。

  Filter:过滤器

    它会在一组资源的前面执行。它可以让请求达到目标资源,也可以终止请求。也就是说 过滤器有拦截请求的能力。

    特性:

      Filter是单例的;与Servlet一样。

    书写过滤器时必须实现Filter接口;并在web.xml中进行配置注册。

    生命周期:

init(FilterConfig);//创建后马上执行进行初始化操作。在服务器启动时就创建
destory();//销毁前执行。在服务器关闭时销毁。
doFilter(ServletRequest,ServletResponse,FilterChain);//每次过滤时都会执行

    web.xml配置

<filter>
    <filter-name>xxx</filter-name>
    <filter-class>cn.filter.xxx</filter-class>
</filter>
<filter-mapping>
    <filter-name>xxx</filter-name>
    <url-pattern>/*</url-pattern><!--所有都拦截-->
</filter-mapping>

    在<filter-mapping>中可以指定要拦截的Servlet。可以指定多个Servlet:<servlet-name></servlet-name>

  FilterConfig:

    与ServletConfig相似。

getInitParameter();//获取初始化参数
getFilterName();//获取过滤器名称
getServletContext();//获取application

  FilterChain:

doFilter(ServletRequest,ServletResponse);//放行。就相当于调用了目标Servlet的service()方法。

  多过滤器:

    FilterChain的doFilter()方法:执行目标资源,或执行下一个过滤器。若没下一个过滤器,那么执行的时目标资源;若有下一个过滤器,那么就性值下一个过滤器。

  过滤器的四种拦截方式:在filter-mapping中进行配置

    1、拦截请求 DISPATCHER:

<dispatcher>REQUEST</dispatcher> <!--默认拦截方式-->

    2、拦截转发 FORWARD:

<dispatcher>FORWARD</dispatcher>

    3、拦截包含 INCLUDE:

<dispatcher>INCLUDE</dispatcher>

    4、拦截错误 ERROR:

<dispatcher>ERROR</dispatcher>

  多个过滤器的执行顺序:

    <filter-mapping>的配置顺序决定了过滤器的执行顺序。

实例:分IP统计访问次数

//1、Listener 在服务器启动时创建Map,保存到ServletContext中
public class AListener implements ServletContextListener{
    public void contextInitialized(ServletContextEvent event){
        Map<String,Integer> map=new LinkedHashMap<String,Integer>();
        ServletContext application=event.getServletContext();
        application.setAttribute("map",map);
    }
}

//2、从application中获取Map,从request中得到当前客户端的IP进行统计工作,结果保存到Map中。
public class AFilter implements Filter{
    
    Private FilterConfig config;
    
    public void init(FilterConfig config) throws ServletException{
        this.config=config;
    }
    
    public void destroy(){
        
    }
    
    public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) throws IOException,ServletException {
        
        ServletContext sc=config.getServletContext();
        Map<String,Integer> map=(Map<String,Integet>) sc.getAttribute("map");
        
        String strIP=request.getRemoteAddr();
        
        if(map.containsKey(strIP)){
            int count=map.get(strIP);
            map.put(strIP,count+1);
        }else{
            map.put(strIP,1);
        }
        app.setAttribute("map",map);
        
        chain.doFilter(request,response);//放行
    }
}

//3、JSP页面forEach展示 items="${applicationScope.map}" var="entry"        ${entry.key}、${entry.key}
View Code

实例:过滤器解决全站字符乱码(POST和GET中文编码问题)

//在Servlet的doGet()、doPost()中只需要处理response的请求的编码问题
response.setContentType("text/html;charset-utf-8");

//1、过滤器
public class EncodingFilter implements Filter{
    public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) throws IOException,ServletException{
        //处理POST请求编码问题
        request.setCharacterEncoding("utf-8");
        //处理GET请求编码问题。用装饰者模式,需要一个request装饰类
        HttpServletRequest req=(HttpServletRequest)request;
        
        if(req.getMethod().equals("GET")){
            EncodingRequest er=new EncodingRequest(req);
            chain.doFilter(er,response);
        }
        chain.doFilter(request,response);
    }
}

/*
* 2、request装饰类:需要实现HttpServletRequest或继承HttpServletRequestWrapper
* HttpServletRequestWrapper:是将除去getParameter()方法外的所有方法都实现了,就是将“一切拜托你”实现了。
*/
public class EncodingRequest extends HttpServletRequestWrapper{
    private HttpServletRequest req;
    public EncodingRequest(HttpServletRequest request){
        super(request);
        this.req=request;
    }
    
    public String getParameter(String name){
        String value=req.getParameter(name);
        try{
            value=new String(value.getBytes("iso-8859-1"),"utf-8");
        }catch(UnsupportedEncodingException ex){
            throw new RuntimeException(ex);
        }
        return value;
    }
}
View Code
原文地址:https://www.cnblogs.com/zltao/p/10429721.html