过滤器和监听器

01 过滤器的简介

为什么使用过滤器?

我们目前书写项目中遇到的问题?
A、目前使用的baseServlet的优点就是方便可以进行乱码的统一的处理,但是如果我们以后不使用servlet,那么我们在进行中文乱码处理的时候就需要在每一个servlet 中去书写,但是比较麻烦。
B、在进行登陆拦截处理的时候,我们需要把拦截的代码在每一个页面中重复的书写,这样,就会变的非常的麻烦。

  最终的问题: 重复的代码在项目中多次的使用书写。 
  解决方案: 过滤器

什么是过滤器?

在这里插入图片描述

02 使用过滤器进行乱码解决

Class文件

public class EncFilter  implements Filter {
     //初始化方法 --执行一次
    String abc;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //UTF-8
        abc = filterConfig.getServletContext().getInitParameter("abc");
    }
    //服务请求方法---执行多次
    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
        //到达目标资源之前的处理操作
        req.setCharacterEncoding(abc);
        //执行下一个过滤器或者目标资源
        chain.doFilter(req,resp);
        //离开服务器之前的处理操作
    }
    //销毁--执行一次
    @Override
    public void destroy() {
    }

web.xml 配置过滤范围

<Filtername> </Filtername>
...

03 使用过滤器进行登陆的控制

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException {
    HttpServletRequest  request=(HttpServletRequest) req;
    HttpServletResponse  response=(HttpServletResponse)resp;

    Object emp = request.getSession().getAttribute("emp");
    String uri = request.getRequestURI();
    String queryString = request.getQueryString();
    System.out.println(uri+"--"+queryString);
if("/sxtoa/login.jsp".equals(uri)||"/sxtoa/servlet/EmployeeServlet?method=empLogin".equals(uri+"?"+queryString)){
        filterChain.doFilter(request,response);
    }else {
        if(emp==null){
            //用户没有登陆           response.sendRedirect(request.getContextPath()+"/login.jsp");
        }else {       //直接放行  --执行目标的资源
            filterChain.doFilter(request,response);
       }
    }
}

04 过滤器更多内容

问题1:多个过滤器,执行的顺序怎么确定?

的顺序确定执行的顺序

问题2:每个请求和响应都要经过过滤器吗?

不是,是否经过过滤器,经过几个过滤器由过滤器的路径来定;
/servlet/ /

问题3:请求和响应时是不是分别将过滤器代码从头到尾执行一遍

不是;请求时执行预处理操作,响应时执行后处理操作;
请求时过滤器的执行顺序如果是1,2,4,响应时过滤器的执行顺序4,2,1

问题4:在过滤器中能否跳转到项目的其他任意资源

可以
举例:如果一个过滤器是进行权限验证,没有登录,就不让访问目标资源,直接跳转到login.jsp

问题5:重定向和转发是否经过过滤器

重定向经过
默认转发不经过,因为是服务器端跳转。可以通过配置解决

05 监听器实现日志记录

监听器简介

监听器: 监听事件,处理事件的对象. 使用观察者设计模式实现的.
观察者设计模式: 分为三个角色, 分别是:事件源, 事件, 监听器.
事件: 就是发生的事情, 其中包含事件源
事件源: 发生事情的根源, 触发事件的资源(对象)(发生事件的场所)
监听器: 处理事件的逻辑., 根据事件,获取事件源,并处理事件.
Servlet中的监听器

代码实现

public class LogListener  implements ServletRequestListener {
    //监听请求销毁
    @Override
    public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
    }
    //监听请求的发出
    @Override
    public void requestInitialized(ServletRequestEvent servletRequestEvent) {
         // XXX 在  XXX时间  访问  程序的XX位置
        ServletRequest servletRequest = servletRequestEvent.getServletRequest();
        HttpServletRequest  request=(HttpServletRequest)servletRequest;
        //获得远程访问的IP地址
        String ip = request.getRemoteAddr();
        //获得访问的时间
        String localeString = new Date().toLocaleString();
        //程序的位置    servlet/uu?method=add

        String requestURI = request.getRequestURI();
        String queryString = request.getQueryString();
        try {
            PrintWriter  out=new PrintWriter(new FileWriter("D:/log.txt",true));
            out.println("用户:"+ip+",在:"+localeString+",访问了程序:"+requestURI+"?"+queryString);
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

06 监听器实现在线人数的统计

public class OnLineListener implements HttpSessionListener,HttpSessionAttributeListener {
    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
    }
    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        ServletContext application = httpSessionEvent.getSession().getServletContext();

        Integer online = (Integer) application.getAttribute("online");
        if(online==null){
            online=0;
        }else {
            online--;
        }
        application.setAttribute("online",online)
    }

    @Override
    public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {

  if("emp".equals(httpSessionBindingEvent.getName())){
            //全局对象
            ServletContext application = httpSessionBindingEvent.getSession().getServletContext();
            //获得当前的在线人数
            Integer online = (Integer) application.getAttribute("online");
            if(online==null){
                //当前没人登陆
                online=1;
            }else {
                //当前有人登陆
                online++;
            }

            //把记录的值重新的设置到application
            application.setAttribute("online",online);
        }
    }
    @Override
    public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
    }
    @Override
    public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
    }
}

07 其他监听器使用

@Override
public void valueBound(HttpSessionBindingEvent httpSessionBindingEvent) {
    System.out.println("valueBound");
}
@Override
public void valueUnbound(HttpSessionBindingEvent httpSessionBindingEvent) {
    // req.getSession().invalidate();
    // req.getSession().removeAttribute("emp");
    System.out.println("valueUnbound");
}
/**
 * 如果想要实现序列化和反序列化需要在Context.xml中
 * <Manager className="org.apache.catalina.session.PersistentManager" saveOnRestart="true">
 <Store className="org.apache.catalina.session.FileStore" directory="E:\apache-tomcat-7.0.79\webapps"/>
 </Manager>
   如果对象想要实现序列化过程,对象上必须实现 Serializable
 *
 * **/
@Override
public void sessionWillPassivate(HttpSessionEvent httpSessionEvent) {
    System.out.println("sessionWillPassivate");
}
@Override
public void sessionDidActivate(HttpSessionEvent httpSessionEvent) {   System.out.println("sessionDidActivate");
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AloneDrifters

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值