Java · 成长之路JavaJava学习笔记

JavaEE-Listener学习笔记

2017-06-07  本文已影响124人  明天你好向前奔跑

Listener

一、Listener

1: 域对象创建和销毁监听器

2: 域对象属性变更监听器


    在使用监听器监听域对象属性变更时,实现其接口后重写三个方法:add,replace,remove。
    分别对应setAttribute()和removeAttribute().
    需要注意的是,重写的监听属性修改和移除的方法时,如果调用getName()和getValue(),
    显示的是其方法执行前的值。

    
    
* HttpSessionAttributeListener
* ServletRequestAttributeListener

3: HttpSession中对象状态感知监听器

测试:javabean:User类实现HttpSessionBindingListener接口

//监听User对象是否存入Session对象。状态自我感知器,需事先监听器接口
部分代码:
public class User implements HttpSessionBindingListener{
    
    public void valueBound(HttpSessionBindingEvent event) {
        System.out.println("User对象存入session域中");
    }

    public void valueUnbound(HttpSessionBindingEvent event) {
        System.out.println("User对象未存入session域中");
    }
自我状态感知监听器监听域中对象与session是否绑定 img02.png

二、 定时器与Calendar日历类

三、 邮件相关概念

收发邮件的原理.png

Java发送邮件的API(了解)

img04.png

四、案例:发送生日祝福邮件

需求:根据数据库中用户的生日在用户生日当天给其发送生日祝福的邮件。

分析:

1. 首先,使用监听器,在服务器一运行时就执行定时器的操作
2. 监听器的操作代码:使每一天的凌晨00:00都能执行发送生日祝福邮件的代码。
    1. listener调用service/dao层查询数据库中是否有当天生日的用户。
    2. 在dao层获取到当天的日期,模糊查询,返回用户的List集合回到Listener的TimerTask中
    3. 调用javaMail的API完成发送邮件的功能

1. 搭建环境

  1. 需要查询数据库,添加所需的jar包:数据库连接驱动,c3p0.jar,c3p0-config.xml,dbutils.jar及JDBCUtils工具类。

    public class JDBCUtils {

        private static DataSource ds = new ComboPooledDataSource();//根据默认配置文件创建连接池
        //创建与线程绑定的存储connection的map集合
        private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>();
        
        //获取连接池的方法
        public static DataSource getDataSource() {
            return ds;
        }
        
        //从连接池中获取连接的方法
        public static Connection getConnection() throws SQLException {
            return ds.getConnection();
        }
        
        //从ThreadLocal中获取与当前线程绑定的链接的方法
        public static Connection getConnectionTL() throws SQLException {
            Connection connection = threadLocal.get();
            if(connection == null) {
                threadLocal.set(getConnection());
                connection = threadLocal.get();
            }
            return connection;
        }
        
        //开启事务的方法
        public static void startTransaction() throws SQLException {
            Connection connection = getConnectionTL();
            connection.setAutoCommit(false);
        }
        
        //提交事务并释放资源的方法
        public static void commitAndRelease() throws SQLException {
            Connection connection = getConnectionTL();
            connection.commit();
            if(connection != null) {
                connection.close();
                connection = null;//置为null以便更快的被gc垃圾回收器回收,释放内存
            }
            threadLocal.remove();//与threadLocal解绑
        }
        
        //回滚事务并释放资源的方法
        public static void roolbackAndRelease() throws SQLException {
            Connection connection = getConnectionTL();
            connection.rollback();
            if(connection != null) {
                connection.close();
                connection = null;
            }
            threadLocal.remove();
        }
    }
准备数据库
3.需要使用到javaMail发送邮件,提供javaMail.jar的jar包和发送邮件的工具类MailUtils
4.搭建邮箱服务器环境,修改邮箱工具类的参数,即发送者的账号密码
4.新建包结构web--service--dao层

2. 代码实现

2.1 使用监听器,在服务器一运行时就执行定时器的操作

public class MyServletContextListener implements ServletContextListener {

//监听服务器启动后执行的方法
public void contextInitialized(ServletContextEvent sce) {
    //使用定时器,让其从服务器启动后的每天凌晨00:00执行该定时器内的TimerTask
    Timer timer = new Timer();
    TimerTask task = new TimerTask() {
        //匿名内部类,实质是该TimerTask具体的子类对象
        @Override
        public void run() { //run方法中写需要定时执行的方法
            System.out.println("定时器执行了---");
            try {
                //调用service/dao层查询用户的当前日期生日的用户
                BirthdayService service = new BirthdayService();
                List<User> list = service.findBirthday();
                
                //遍历list集合,获取到每个用户的邮箱,更改MailUtils的参数,调用方法发送邮件
                for (User user : list) {
                    String receiver = user.getEmail();
                    String emailBody = "亲爱的"+user.getName()+",祝你生日快乐!";
                    MailUtils.sendMail(receiver, emailBody);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            
        }
    };
    
    //参数1:设置定时器要执行的方法:这里要写发送邮件的功能,需要等服务器返回用户的信息后编写
    //参数2: 可以写两种参数,可以写具体的Date日期指定某个时间执行,也可以填入距离当前时间后的多少毫秒值执行
    //参数3:隔多少毫秒执行一次该定时器方法,这里写的1天
    Long delayTime = DateUtils.getDelayTime();//当前时间距离明天零点的延迟时间
    //timer.scheduleAtFixedRate(task, delayTime, 24*60*60*1000);
    //为了测试,将执行方法的参数2改为0,参数3设为1000,即服务器启动立即执行,每隔1秒钟执行一次
    timer.scheduleAtFixedRate(task, 0, 1000);
}

2.2 编写service层

BirthdayDAO dao = new BirthdayDAO();
//获取到当前时间 ,格式: 06-07
String birthday = DateUtils.getCurrentMonth()+"-"+DateUtils.getCurrentDay();
return dao.findBirthday(birthday);

2.3 编写dao层

QueryRunner runner = new QueryRunner(JDBCUtils.getDataSource());
String sql = "select * from user where birthday like ?";
System.out.println(birthday);
return runner.query(sql, new BeanListHandler<User>(User.class), "%"+birthday);

2.4 DateUtils工具类

public class DateUtils {

    /**
     * 获得当前时间距离指定日期零点的延迟时间
     * 
     * @param amount
     * @return
     */
    public static Long getDelayTime(int amount) {
        // 1 设置当前时间
        Calendar calendar = Calendar.getInstance();
        Date newDate = new Date();
        calendar.setTime(newDate);
        // 2 将时分秒设置成0
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        // 3 设置指定天数
        calendar.add(Calendar.DATE, amount);
        // 4 计算当前时间距离设置日期零点的延迟时间
        return calendar.getTimeInMillis() - newDate.getTime();
    }

    /**
     * 当前时间距离明天零点的延迟时间
     * 
     * @return
     */
    public static Long getDelayTime() {
        return getDelayTime(1);
    }

    /**
     * 获得一天的毫秒值
     * 
     * @return
     */
    public static Long getOneDay() {
        return 24 * 60 * 60 * 1000L;
    }

    /**
     * 获得当前时间的月份(两位)
     * 
     * @return
     */
    public static String getCurrentMonth() {
        // 1 设置当前时间
        Calendar calendar = Calendar.getInstance();
        Date newDate = new Date();
        calendar.setTime(newDate);

        int m = calendar.get(Calendar.MONTH) + 1;
        if (m < 10) {
            return "0" + m;
        }
        return "" + m;
    }

    /**
     * 获得当前时间中的几号(两位)
     * 
     * @return
     */
    public static String getCurrentDay() {
        // 1 设置当前时间
        Calendar calendar = Calendar.getInstance();
        Date newDate = new Date();
        calendar.setTime(newDate);

        int d = calendar.get(Calendar.DATE);
        if (d < 10) {
            return "0" + d;
        }
        return "" + d;
    }

    public static void main(String[] args) {
        System.out.println(getCurrentMonth());
        System.out.println(getCurrentDay());
    }
}

2.5 测试结果

img06.png img07.png
上一篇下一篇

猜你喜欢

热点阅读