zoukankan      html  css  js  c++  java
  • Java三大器(过滤器|监听器|拦截器)

    filter过滤器

    用的功能很简单,但是很重要(做框架的时候可能才会用得很深)

    平时用就是实现一下Filter接口(重写它得doFliter(),init(),destroy()方法,放行chain.doFilter(request,response);),并在web.xml里边进行配置就完事了

    另外一个是它的最佳实践:

    公共代码得提取(如request,response指定编码解码方式,公共代码提到一块(处理post))

    对request,response的方法进行增强(装饰者模式(包装,同样是乱码处理,使处理参数的能力更强大,支持中文(处理get))/动态代理(反射))(自动登陆)

    进行权限控制

    //装饰者模式(这个模式也很好记,就是你想用request对象的时候,你又希望它的getParameter()方法更加强大,可以处理中文,那么你可以建一个新类,对它的方法进行增强)
    //(应用场景:不想增加很多子类/只想增强类的一些方法,例如在EncodingFilter过滤器中对request的getParameter方法进行增强,处理其中文参数乱码问题)
    public class EncodingFilter implements Filter{
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            
            //在传递request之前对request的getParameter方法进行增强
            /*
             * 装饰者模式(包装)
             * 
             * 1、增强类与被增强的类要实现统一接口(继承同一个父类)
             * 2、在增强类中传入被增强的类(构造)
             * 3、需要增强的方法重写 不需要增强的方法调用被增强对象的
             * 
             */
            
            //被增强的对象req
            HttpServletRequest req = (HttpServletRequest) request;
            //增强对象enhanceRequest
            EnhanceRequest enhanceRequest = new EnhanceRequest(req);
            
            
            chain.doFilter(enhanceRequest, response);
        }
    
        @Override
        public void destroy() {
            
        }
        
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            
        }
    }
    
    class EnhanceRequest extends HttpServletRequestWrapper{
        //HttpServletRequestWrapper这个包装类就是专门用来你继承,进而写增强方法的
        private HttpServletRequest request;
    
        public EnhanceRequest(HttpServletRequest request) {//核心:传入被增强的类
            super(request);
            this.request = request;
        }
        
        //对getParaameter增强,增强的是原来类的方法
        @Override
        public String getParameter(String name) {
            String parameter = request.getParameter(name);//乱码
            try {
                parameter = new String(parameter.getBytes("iso8859-1"),"UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            return parameter;
        }
    }

    Listener监听器

    监听三个域对象:request,session,servletContext

     ServletContext代表整个web应用,只有一个

    步骤:实现接口,覆盖方法,xml中进行配置

    ServletContextListener

    方法中可以获取到被监听的对象(两方法,一个是通用的)

    应用:

    web应用一创建,加载数据库驱动,连接池的初始话

    加载spring初始配置文件(applicationContext.xml)

    任务调度(定时器:Timer/TimeTask)

     HttpSession(多个)

    服务端没有某浏览器对应的session时创建

     3种销毁:应用正常关闭,手动销毁,过期(默认30min)

    应用:统计访问量

    ServletRequest(瞬间的事)

    ServletContext,HttpSession,ServletRequest三个域对象的属性变化(getAttribute,setAttribute,removeAttribute)

    对象感知监听器((绑定,解绑)(钝化,活化)),(对象需要实现接口,不需要配置xml)

    绑定状态:就一个对象被放到session域中
    解绑状态:就是这个对象从session域中移除了
    钝化状态:是将session内存中的对象持久化(序列化)到磁盘
    活化状态:就是将磁盘上的对象再次恢复到session内存中

    package com.itheima.domian;
    
    import javax.servlet.http.HttpSessionBindingEvent;
    import javax.servlet.http.HttpSessionBindingListener;
    
    public class Person implements HttpSessionBindingListener{
    
        private String id;
        private String name;
        public String getId() {
            return id;
        }
        public void setId(String id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        
        
        @Override
        //绑定的方法
        public void valueBound(HttpSessionBindingEvent event) {
            System.out.println("person被绑定了");
        }
        @Override
        //解绑方法
        public void valueUnbound(HttpSessionBindingEvent event) {
            System.out.println("person被解绑了");
        }
        
        
        
    }
    Person p = new Person();
    p.setId("100");
    p.setName("zhangsanfeng");
    
    //将person对象绑到session中
    session.setAttribute("person", p);
    
    //将person对象从session中解绑
    session.removeAttribute("person");

    一个对象必须要实现了Serializable接口,才能被存储到磁盘上

    钝化:服务器正常关闭时,session中的对象会被钝化到磁盘

    活化:服务器正常启动时,session会活化这个对象(外界又可以正常的访问这个session了)

    另外,钝化和活化你可以进行主动控制(context.xml,默认配置1分钟不用被销毁)

    package com.itheima.domian;
    
    import java.io.Serializable;
    import javax.servlet.http.HttpSessionActivationListener;
    import javax.servlet.http.HttpSessionEvent;
    
    public class Customer implements HttpSessionActivationListener,Serializable{
    
        private String id;
        private String name;
        
        public String getId() {
            return id;
        }
        public void setId(String id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        
        
        @Override
        //钝化
        public void sessionWillPassivate(HttpSessionEvent se) {
            System.out.println("customer被钝化了");
        }
        @Override
        //活化
        public void sessionDidActivate(HttpSessionEvent se) {
            System.out.println("customer被活化了");
        }
        
        
    }
    <?xml version="1.0" encoding="UTF-8"?>
    <Context>
        <!-- maxIdleSwap:session中的对象多长时间不使用就钝化 -->
        <!-- directory:钝化后的对象的文件写到磁盘的哪个目录下 配置钝化的对象文件在 work/catalina/localhost/钝化文件 -->
        <Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
            <Store className="org.apache.catalina.session.FileStore" directory="itheima32" />
        </Manager>
    </Context>

    Listener 监听器结合Timer定时任务实现每天定时给过生日的员工发邮件

      <listener>
          <listener-class>com.itheima.birthday.BirthdayListener</listener-class>
      </listener>
    package com.itheima.birthday;
    
    import java.sql.SQLException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.List;
    import java.util.Timer;
    import java.util.TimerTask;
    
    import javax.mail.MessagingException;
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    
    import org.apache.commons.dbutils.QueryRunner;
    import org.apache.commons.dbutils.handlers.BeanListHandler;
    
    import com.itheima.mail.MailUtils;
    
    public class BirthdayListener implements ServletContextListener{
    
        @Override
        public void contextInitialized(ServletContextEvent sce) {
            //当web应用启动 开启任务调动---功能在用户的生日当前发送邮件
            //开启一个定时器
            Timer timer = new Timer();
            timer.scheduleAtFixedRate(new TimerTask() {
                
                @Override
                public void run() {
                    // 为当前的生日的用户发邮件
                    //1、获得今天过生日的人
                    //获得今天的日期
                    SimpleDateFormat format = new SimpleDateFormat("MM-dd");
                    String currentDate = format.format(new Date());
                    //根据当前时间从数据查询今天过生日的人
                    QueryRunner runner = new QueryRunner(DataSourceUtils.getDataSource());
                    String sql = "select * from customer where birthday like ?";
                    List<Customer> customerList = null;
                    try {
                        customerList = runner.query(sql, new BeanListHandler<Customer>(Customer.class) ,"%"+currentDate+"%");
                    } catch (SQLException e) {
                        e.printStackTrace();
                    } //08-18
                    //2、发邮件
                    if(customerList!=null&&customerList.size()>0){
                        for(Customer c : customerList){
                            String emailMsg = "亲爱的:"+c.getRealname()+",生日快乐!";
                            try {
                                MailUtils.sendMail(c.getEmail(), "生日祝福", emailMsg);
                                System.out.println(c.getRealname()+"邮件发送完毕");
                            } catch (MessagingException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                    
                    
                }
            }, new Date(), 1000*10);
            //实际开发中起始时间是一个固定的时间
            //实际开发中间隔时间是1天
        }
    
        @Override
        public void contextDestroyed(ServletContextEvent sce) {
            
        }
    
    }

    Interceptor拦截器

    Java三大器:过滤器,监听器,拦截器Interceptor

    拦截器是依赖Java反射机制来实现的。拦截器的实现,用到的是JDK实现的动态代理,我们都知道,JDK实现的动态代理,需要依赖接口。拦截器

    是在面向切面编程中应用的,就是在你的service或者一个方法前调用一个方法,或者在方法后调用一个方法。拦截器不是在web.xml,比如struts在

    struts.xml中配置。

    过滤器可以简单的理解为“取你所想取”,过滤器关注的是web请求;拦截器可以简单的理解为“拒你所想拒”,拦截器关注的是方法调用

    击石乃有火,不击元无烟!!
  • 相关阅读:
    怎样评价海贼王中艾斯的死?
    interleaving-string
    打败微信的将是怎么样的一款产品?
    javascript实例——文本特效篇(包含3个小例子)
    javascript实例——时间日期篇(包含5个实例)
    【转】Js获取当前日期时间及其它操作
    【转】外国朋友出的js题目,你能对几道
    【转】30+有用的CSS代码片段
    php的ajax简单实例
    Border属性的各种变化
  • 原文地址:https://www.cnblogs.com/rain2020/p/12694181.html
Copyright © 2011-2022 走看看