首頁 > IT教程 > 正文

JAVA監聽器

2020-02-14 17:32:04 來源:金橙教程網 作者:admin8 瀏覽:78次 「手機版」

監聽

作為JAVA開發人員,我們應對javaweb的三個技術要點之一的Listener進行學習,樓主查閱相關資料并學習相關視頻,總結如下JAVA監聽器內容,供大家參考學習。完整代碼內容我已放到我的github中,請自行下載:https://github.com/Mr-WangZhe/Java-Listener“>JAVA Listener學習

一.監聽器Listener

1.什么是監聽器

  • 監聽器就是監聽某個域對象的的狀態變化的組件
  • 監聽器的相關概念:

    • 事件源:被監聽的對象(三個域對象 request、session、servletContext)
    • 監聽器:監聽事件源對象事件源對象的狀態的變化都會觸發監聽器(6+2)
    • 注冊監聽器:將監聽器與事件源進行綁定
    • 響應行為:監聽器監聽到事件源的狀態變化時所涉及的功能代碼(程序員編寫代碼)

2.監聽器有哪些

  • 第一維度按照被監聽的對象劃分:ServletRequest域、HttpSession域、ServletContext域
  • 第二維度按照監聽的內容分:監聽域對象的創建與銷毀的、監聽域對象的屬性變化的

這里寫圖片描述

3.監聽三大域對象的創建與銷毀的監聽器

  • 監聽器的編寫步驟(重點):

    • 編寫一個監聽器類去實現監聽器接口
    • 覆蓋監聽器的方法
    • 需要在web.xml中進行配置—注冊
  • 監聽ServletContext域的創建與銷毀的監聽器ServletContextListener

    • Servlet域的生命周期

      • 何時創建:服務器啟動創建
      • 何時銷毀:服務器關閉銷毀
    • ServletContextListener監聽器的主要作用

      • 初始化的工作:初始化對象、初始化數據(加載數據庫驅動、連接池的初始化)
      • 加載一些初始化的配置文件(spring的配置文件)
      • 任務調度(定時器—Timer/TimerTask)
    • 實例應用:

    • 整體流程:create包下創建MyServletContextListener類實現ServletContextListener接口并覆蓋方法public void contextInitialized(ServletContextEvent arg0)監聽context域對象的創建;覆蓋方法public void contextDestroyed(ServletContextEvent arg0)監聽context域對象的銷毀。并在web.xml中通過<listener>中的<listener-class>書寫監聽器全類名配置。

    • 實現任務調度(即定時器)的思路:使用Timer類對象的scheduleAtFixedRate(task,firstTime,period)方法第一個參數書寫TimerTask()的匿名內部類重寫run方法從而實現調度任務內容;firstTime是Date類型對象,我們可以設置成當前晚上12點;period是間隔執行時間(單位毫秒),我們可以設置成24小時。從而實現從當前晚上12點開始,每24小時都執行對應的調度任務。

    • 實例代碼:

      //web.xml
      <?xml version="1.0" encoding="UTF-8"?>
      <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
      <!-- 注冊監聽器 -->
      <listener>
          <listener-class>create.MyServletContextListener</listener-class>
      </listener>
      <display-name>WEB23_LISTENER</display-name>
      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
      </web-app>
      
      //MyServletContextListener.java
      package create;
      import java.text.ParseException;
      import java.text.SimpleDateFormat;
      import java.util.Date;
      import java.util.Timer;
      import java.util.TimerTask;
      import javax.servlet.ServletContext;
      import javax.servlet.ServletContextEvent;
      import javax.servlet.ServletContextListener;
      public class MyServletContextListener implements ServletContextListener{
      //監聽context域對象的創建
      @Override
      public void contextInitialized(ServletContextEvent arg0) {//參數可以獲得被監聽的對象
      //        ServletContext servletContext1 = arg0.getServletContext();//返回值是被監聽的對象
      //        Object servletContext2 = arg0.getSource();//等同于arg0.getServletContext(),獲得的是Object類型,但實際上也是獲得被監聽的對象
      //        System.out.println("context創建了...");
          //開啟一個計息任務調度——每天晚上12點計息一次
          Timer timer = new Timer();
          //task任務,firstTime第一次執行的時間,period間隔執行的時間(單位毫秒)
          //timer.scheduleAtFixedRate(task, firstTime, period);
          //測試demo:從服務器啟動開始每隔5秒打印“銀行計息了”
      //        timer.scheduleAtFixedRate(new TimerTask() {
      //            @Override
      //            public void run() {
      //                System.out.println("銀行計息了...");
      //            }
      //        }, new Date(), 5000);
          //實際銀行計息業務
          //1.起始時間,定義成晚上12點
          //2.間隔時間:24小時
          SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
          String currentTime = "2018-08-15 00:00:00";
          Date date = null;
          try {
              date = format.parse(currentTime);
          } catch (ParseException e) {
              e.printStackTrace();
          }
          timer.scheduleAtFixedRate(new TimerTask() {
              @Override
              public void run() {
                  System.out.println("銀行計息了...");
              }
          }, date, 24*60*60*1000);
      }
      //監聽context域對象的銷毀
      @Override
      public void contextDestroyed(ServletContextEvent arg0) {
          System.out.println("context銷毀了...");
      }
      }
  • 監聽Httpsession域的創建于銷毀的監聽器HttpSessionListener

    • HttpSession對象的生命周期

      • 何時創建:第一次調用request.getSession時創建
      • 何時銷毀:服務器關閉銷毀、session過期(默認30分鐘,修改默認的30分鐘是在Tomcat的web.xml,修改當前項目的過期時間是在自己項目的web.xml中)、手動銷毀
    • HttpSessionListener監聽器的主要作用:

      • 由于每次訪問網站都會默認創建session對象(jsp頁面中page指令中的session屬性默認為true,即被訪問時創建session),可以用于計數網站訪問過的人
    • 實例應用:

      • 整體流程:創建MyHttpSessionListener類實現HttpSessionListener接口并覆蓋public void sessionCreated(HttpSessionEvent arg0)public void sessionDestroyed(HttpSessionEvent arg0)方法。并在web.xml中注冊該listener,和index.jsp頁面。每當訪問一次index頁面,即會調用一次sessionCreated方法。

      • 實例代碼:

      //web.xml
      <?xml version="1.0" encoding="UTF-8"?>
      <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
      <!-- 注冊監聽器 -->
      <listener>
          <listener-class>create.MyHttpSessionListener</listener-class>
      </listener>
      <display-name>WEB23_LISTENER</display-name>
      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
      </web-app>
      
      //MyHttpSessionListener.java
      package create;
      import javax.servlet.http.HttpSessionEvent;
      import javax.servlet.http.HttpSessionListener;
      public class MyHttpSessionListener implements HttpSessionListener{
      @Override
      public void sessionCreated(HttpSessionEvent arg0) {
          //獲得Session對象的方法arg0.getSession()
          String id = arg0.getSession().getId();
          System.out.println("session創建"+id);
      
      }
      @Override
      public void sessionDestroyed(HttpSessionEvent arg0) {
          System.out.println("session銷毀");
      
      }
      }
      
      //index.jsp
      <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
      <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
      <html>
      <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <title>Insert title here</title>
      </head>
      <body>
      index.jsp
      </body>
      </html>
  • 監聽ServletRequest域創建與銷毀的監聽器ServletRequestListener

    • ServletRequest的生命周期

      • 創建:每一次請求都會創建request
      • 銷毀:請求結束
    • 用法同上,用處不是很大,此處省略。

4.監聽三大域對象的屬性變化的

  • 域對象的通用的方法:

    • setAttribute(name,value)

      • 觸發添加屬性的監聽器的方法
      • 觸發修改屬性的監聽器的方法
    • getAttribute(name)
    • removeAttribute(name)

      • 觸發刪除屬性的監聽器的方法
  • ServletContextAttibuteListener監聽器

    • 整體使用流程:定義類MyServeltContextAttributeListener實現ServeltContextAttributeListener接口并覆蓋public void attributeAdded(ServletContextAttributeEvent arg0) ;public void attributeRemoved(ServletContextAttributeEvent arg0);public void attributeReplaced(ServletContextAttributeEvent arg0)三個方法。在attributeAdded方法中的參數傳遞的ServletContextAttributeEvent實例對象中,調用getName方法獲取放到域中的name,調用getValue方法獲取放到域中的value;在attributeRemoved方法中的參數傳遞的ServletContextAttributeEvent實例對象中,調用getName方法獲取被刪除的域中的name,調用getValue方法獲取被刪除的域中的value;在attributeReplaced 方法中的參數傳遞的ServletContextAttributeEvent實例對象中,調用getName方法獲取修改前的域中的name,調用getValue方法獲取修改前的域中的value。并在web.xml中注冊監聽器。

    • 實例代碼:

    //MyServletContextAttributeLister.java
    package attribute;
    import javax.servlet.ServletContextAttributeEvent;
    import javax.servlet.ServletContextAttributeListener;
    public class MyServletContextAttributeListener implements ServletContextAttributeListener{
        @Override
        public void attributeAdded(ServletContextAttributeEvent arg0) {
            //添加屬性時的監聽方法
            System.out.println(arg0.getName());//獲得放到域中的name
            System.out.println(arg0.getValue());//獲得放到域中的value
        }
        @Override
        public void attributeRemoved(ServletContextAttributeEvent arg0) {
            //移除屬性時的監聽方法
            System.out.println(arg0.getName());//刪除的域中的name
            System.out.println(arg0.getValue());//刪除的域中的value
        }
        @Override
        public void attributeReplaced(ServletContextAttributeEvent arg0) {
            //修改屬性時的監聽方法
            System.out.println(arg0.getName());//獲得修改前的域中的name
            System.out.println(arg0.getValue());//獲得修改前的域中的value
        }
    }
    
    //web.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
      <listener>
        <listener-class>attribute.MyServletContextAttributeListener</listener-class>
      </listener>
      <display-name>WEB23_LISTENER</display-name>
      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
      <servlet>
        <description></description>
        <display-name>TestMyServletContextAttributeListener</display-name>
        <servlet-name>TestMyServletContextAttributeListener</servlet-name>
        <servlet-class>attribute.TestMyServletContextAttributeListener</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>TestMyServletContextAttributeListener</servlet-name>
        <url-pattern>/test1</url-pattern>
      </servlet-mapping>
    </web-app>
    
    //用于測試的接口TestMyServletContextAttributeListener.java
    package attribute;
    import java.io.IOException;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    public class TestMyServletContextAttributeListener extends HttpServlet {
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            ServletContext context = this.getServletContext();
            //向context域中存數據
            context.setAttribute("name", "tom");
            //改context數據
            context.setAttribute("name", "lucy");
            //刪context數據
            context.removeAttribute("name");
        }
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    }

    當調用context.setAttribute(“name”, “tom”)時打印name tom;當調用context.setAttribute(“name”, “lucy”)時打印name tom;當調用context.removeAttribute(“name”)時打印name lucy。

  • HttpSessionAttributeListener監聽器(同上)

  • ServletRequestAriibuteListenr監聽器(同上)

5.與session中的綁定的對象相關的監聽器(對象感知監聽器)

  • 即將要被綁定到session中的對象有幾種狀態

    • 綁定狀態:就一個對象被放到session域中(setAttribute)

    • 解綁狀態:就是這個對象從session域中移除了(removeAttribute)

    • 鈍化狀態:是將session內存中的對象持久化(序列化)到磁盤

    • 活化狀態:就是將磁盤上的對象再次恢復到session內存中(注意對象必須實現Serializable

    接口)

  • 綁定與解綁的監聽器HttpSessionBindingListener(綁在對象上的,且不用在web.xml配置

    • 流程:創建對象實現HttpSessionBindingListener 接口中的public void valueBound(HttpSessionBindingEvent arg0)(綁定的方法,將對象放到session時觸發)和public void valueUnbound(HttpSessionBindingEvent arg0)(解綁的方法,將對象從session中移除時觸發)。

    • 實例代碼:

    //Person.java創建Person類
    package 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 String toString() {
            return "Person [id=" + id + ", name=" + name + "]";
        }
        public Person(String id, String name) {
            super();
            this.id = id;
            this.name = name;
        }
        public Person() {
            super();
        }
        @Override
        public void valueBound(HttpSessionBindingEvent arg0) {
            // 綁定的方法,將person對象放到session時觸發
            System.out.println("Person被綁定");
        }
        @Override
        public void valueUnbound(HttpSessionBindingEvent arg0) {
            // 解綁的方法,將person對象從session移除時觸發
            System.out.println("Person被解綁");
        }
    }
    
    //TestPersonBindingServlet.java
    package domian;
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    public class TestPersonBindingServlet extends HttpServlet {
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            HttpSession session = request.getSession();
            //將person對象綁定到session中
            Person p = new Person("100","jack");
            session.setAttribute("person",p);
            //將person對象從session中解綁
            session.removeAttribute("person");
        }
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    }

    當訪問接口時,代碼執行到session.setAttribute("person",p);時輸出Person被綁定;代碼執行到session.removeAttribute("person");時輸出Person被解綁。

  • 鈍化與活化的監聽器HttpSessionActivationListener 【重要:用于服務器優化】

    • 默認:實現了HttpSessionActivationListener(覆蓋其中的public void sessionDidActivate(HttpSessionEvent arg0)public void sessionWillPassivate(HttpSessionEvent arg0)方法)和Serializable接口(注意必須實現Serializable接口)的對象,被放入到session后,當服務器stop時,session會被鈍化到work/catalina/localhost中命名為SESSIONS.ser;當服務器start時,session會被活化到session域中。

    • 手動設置鈍化時間和存儲位置(通過配置文件指定對象鈍化時間—對象多長時間不用被鈍化):

      • 在META-INF下創建一個context.xml

      • context.xml中的代碼:

      <?xml version="1.0" encoding="UTF-8"?>
      <Context>
      <!-- maxIdleSwap:session中的對象多長時間不使用就鈍化(單位:分鐘),注意鈍化和銷毀的概念完全不同 -->
      <!-- directory:鈍化后的對象的文件寫到磁盤的哪個目錄下配置鈍化的對象文件在 work/catalina/localhost/鈍化文件 -->
      <Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1"><!-- Manager是處理內容的對象 -->
          <Store className="org.apache.catalina.session.FileStore" directory="storeFile" /><!-- Store是做存儲的對象 -->
      </Manager>
      </Context>
    • 實例代碼:

    //Customer.java
    package 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 String toString() {
            return "Customer [id=" + id + ", name=" + name + "]";
        }
        public Customer(String id, String name) {
            super();
            this.id = id;
            this.name = name;
        }
        public Customer() {
            super();
        }
        @Override
        public void sessionDidActivate(HttpSessionEvent arg0) {
            //活化
            System.out.println("customer被活化了");
        }
        @Override
        public void sessionWillPassivate(HttpSessionEvent arg0) {
            //鈍化
            System.out.println("customer被鈍化了");
        }
    }
    
    //TestCustomerActiveServlet.java 用于將customer對象放至session中
    package domian;
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    public class TestCustomerActiveServlet extends HttpServlet {
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            HttpSession session = request.getSession();
            //將customer放到session中
            Customer customer = new Customer("200","lucy");
            session.setAttribute("customer", customer);
            System.out.println("customer被放到session中");
        }
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    }
    
    //TestCustomerActiveServlet2 用于測試session對象是否被活化
    package domian;
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    public class TestCustomerActiveServlet2 extends HttpServlet {
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            HttpSession session = request.getSession();
            //從session域中獲取customer
            Customer customer = (Customer)session.getAttribute("customer");
            System.out.println(customer.getName());
        }
        public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    }
  • 面試題:當用戶很多時,怎樣對服務器進行優化?

    通過session的鈍化與活化,將長期不操作的session內存中的對象持久化到磁盤,為服務器騰出空間,等到用戶再次開始操作時將磁盤上的對象恢復到session內存中。

二.郵箱服務器

1.郵箱服務器的基本概念

  • 郵件的客戶端:可以只安裝在電腦上的也可以是網頁形式的

  • 郵件服務器:起到郵件的接受與推送的作用

  • 郵件發送的協議:

    • 協議:就是數據傳輸的約束
    • 接受郵件的協議:POP3、 IMAP
    • 發送郵件的協議:SMTP
  • 郵箱服務器地址

這里寫圖片描述

2.郵件發送過程

這里寫圖片描述

? 過程描述:如果想利用163客戶端發送郵件給騰訊郵箱用戶,需要先發送給網易郵箱服務器(采用SMTP協議),網易郵箱服務器的SMTP推送給騰訊郵箱服務器的SMTP協議,騰訊郵箱服務器的SMTP將接受到的郵件存儲到一個公共區域。當騰訊客戶端用戶想要接收郵件時,需要發請求給騰訊郵箱服務器(采用POP3協議),該請求會到公共區域取郵件,返回給用戶。

3.郵箱服務器的安裝

  • 安裝使用易郵郵件服務器
  • 工具 —> 服務器設置 ->設置單域名如jack.com,即用戶名為:用戶名@jack.com
  • 新賬號 —> 輸入賬號和密碼 —> 點擊確認即創建用戶

4.郵箱客戶端的安裝

  • 安裝Foxmail
  • 郵箱 —> 新建郵箱賬戶 —> 寫上方的電子郵件及密碼并點擊next —> 設置接受郵件服務器ip和發送ip均為localhost(本機測試使用)
  • 新建兩個用戶可以互相發郵件,接受郵件即可
  • 注意:想要接受時需要點擊收郵件,因為客戶端不是實時刷新的,是固定時間一刷新

5.使用程序發送郵件

  • 使用mail.jar,內部就有發郵件的API

  • 使用MailUtils.java工具類實現發郵件的功能【開發時直接使用即可,不需要背】

    • 郵件發送流程

      • 創建一個程序與郵件服務器會話對象Session
      • 創建一個Message,它相當于是郵件內容
      • 創建Transport用于將郵件發送
    • 工具代碼:
    package mail;
    import java.util.Properties;
    import javax.mail.Authenticator;
    import javax.mail.Message;
    import javax.mail.MessagingException;
    import javax.mail.PasswordAuthentication;
    import javax.mail.Session;
    import javax.mail.Transport;
    import javax.mail.internet.AddressException;
    import javax.mail.internet.InternetAddress;
    import javax.mail.internet.MimeMessage;
    import javax.mail.internet.MimeMessage.RecipientType;
    //郵件工具包
    public class MailUtils {
    //email:郵件發給誰(收件人)  subject:主題  emailMsg:郵件內容
    public static void sendMail(String email,String subject, String emailMsg)
            throws AddressException, MessagingException {
        // 1.創建一個程序與郵件服務器會話對象 Session
        Properties props = new Properties();
        props.setProperty("mail.transport.protocol", "SMTP");//發郵件的協議SMTP
        props.setProperty("mail.host", "192.168.1.109");//發送郵件的服務器地址
        props.setProperty("mail.smtp.auth", "true");// 是否要驗證,指定驗證為true
        // 創建驗證器
        Authenticator auth = new Authenticator() {
            public PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("sam", "111111");//發郵件的賬號驗證
            }
        };
        //此處的session是會話對象
        Session session = Session.getInstance(props, auth);
        // 2.創建一個Message,它相當于是郵件內容
        Message message = new MimeMessage(session);
        message.setFrom(new InternetAddress("[email protected]")); // 設置發送者
        message.setRecipient(RecipientType.TO, new InternetAddress(email)); // 設置發送方式與接收者
        message.setSubject(subject);
        message.setContent(emailMsg, "text/html;charset=utf-8");
        // 3.創建Transport用于將郵件發送
        Transport.send(message);
    }
    }
  • 調用郵件工具類發送郵件

    • 實例代碼:
    package mail;
    import javax.mail.MessagingException;
    import javax.mail.internet.AddressException;
    public class SendMailTest {
    public static void main(String[] args) throws AddressException, MessagingException {
        MailUtils.sendMail("[email protected]", "測試郵件", "這是一封測試郵件");
    }
    }

三.案例(定時發送生日祝福)

  • Demo應用jar包

    • c3p0-0.9.1.2.jar
    • commons-dbutils-1.4.jar
    • mail.jar
    • mysql-connector-java-5.0.4-bin.jar
  • 項目思路:

    • 在web應用創建后,當日12點開啟任務調度,實現給當天生日的用戶發送祝福郵件(本項目作為測試階段,設置自web應用創建后,每隔10秒鐘給當日生日的用戶發送祝福郵件)
    • 遍歷數據庫查看當天過生日的人,借助mail.jar提供的API和MailUtils工具發送郵件
  • 代碼編寫流程:

    • 創建BirthdayListener類實現ServletContextListener,重寫對應方法,主要添加contextInitialized()方法中的內容,利用Timer對象的scheduleAtFixedRate()方法開啟任務調度,設置第一個參數為調度任務內容,分別是查詢數據庫當日過生日的人,發送郵件;設置第二個參數為當前時刻,即項目創建時刻起開啟任務調度;設置第三個參數為間隔時長(單位毫秒)
    package 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.mail.internet.AddressException;
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    import org.apache.commons.dbutils.QueryRunner;
    import org.apache.commons.dbutils.handlers.BeanListHandler;
    import mail.MailUtils;
    public class BirthdayListener implements ServletContextListener{
    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
        //銷毀
    }
    @Override
    public void contextInitialized(ServletContextEvent arg0) {
        //當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());
                System.out.println(currentDate);
                //根據當前時間到數據庫查今天過生日的人
                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) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                //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 (AddressException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } catch (MessagingException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
    
            }
        }, new Date(), 1000*10);
        //實際開發中起始時間是一個固定時間
        //實際開發中間隔時間是1天
    }
    }
  • 開發時應用到Customer實體類進行映射,MailUtils工具發送郵件,web.xml配置監聽器

    //Customer.java
    package birthday;
    public class Customer {
    private int id;
    private String username;
    private String password;
    private String realname;
    private String birthday;
    private String email;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getRealname() {
        return realname;
    }
    public void setRealname(String realname) {
        this.realname = realname;
    }
    public String getBirthday() {
        return birthday;
    }
    public void setBirthday(String birthday) {
        this.birthday = birthday;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    @Override
    public String toString() {
        return "Customer [id=" + id + ", username=" + username + ", password=" + password + ", realname=" + realname
                + ", birthday=" + birthday + ", email=" + email + "]";
    }
    public Customer(int id, String username, String password, String realname, String birthday, String email) {
        super();
        this.id = id;
        this.username = username;
        this.password = password;
        this.realname = realname;
        this.birthday = birthday;
        this.email = email;
    }
    public Customer() {
        super();
    }
    }
    
    //MailUtils.java
    package mail;
    import java.util.Properties;
    import javax.mail.Authenticator;
    import javax.mail.Message;
    import javax.mail.MessagingException;
    import javax.mail.PasswordAuthentication;
    import javax.mail.Session;
    import javax.mail.Transport;
    import javax.mail.internet.AddressException;
    import javax.mail.internet.InternetAddress;
    import javax.mail.internet.MimeMessage;
    import javax.mail.internet.MimeMessage.RecipientType;
    //郵件工具包
    public class MailUtils {
    //email:郵件發給誰(收件人)  subject:主題  emailMsg:郵件內容
    public static void sendMail(String email,String subject, String emailMsg)
            throws AddressException, MessagingException {
        // 1.創建一個程序與郵件服務器會話對象 Session
        Properties props = new Properties();
        props.setProperty("mail.transport.protocol", "SMTP");//發郵件的協議SMTP
        props.setProperty("mail.host", "192.168.1.109");//發送郵件的服務器地址
        props.setProperty("mail.smtp.auth", "true");// 是否要驗證,指定驗證為true
        // 創建驗證器
        Authenticator auth = new Authenticator() {
            public PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("sam", "111111");//發郵件的賬號驗證
            }
        };
        //此處的session是會話對象
        Session session = Session.getInstance(props, auth);
        // 2.創建一個Message,它相當于是郵件內容
        Message message = new MimeMessage(session);
        message.setFrom(new InternetAddress("[email protected]")); // 設置發送者
        message.setRecipient(RecipientType.TO, new InternetAddress(email)); // 設置發送方式與接收者
        message.setSubject(subject);
        message.setContent(emailMsg, "text/html;charset=utf-8");
        // 3.創建Transport用于將郵件發送
        Transport.send(message);
    }
    }
    
    //web.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
    <listener>
      <listener-class>birthday.BirthdayListener</listener-class>
    </listener>
    <display-name>WEB23_LISTENER</display-name>
    <welcome-file-list>
      <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
    </web-app>

相關閱讀

Java操作數據庫方式(六)DataSource詳解

##概述 在java世界里操作數據庫有很多方式,在眾多方式中除了JDBC外都有DataSource對象。 DataSource可以看作數據源,它封裝了數據

java多線程編程實例

這篇文章主要介紹了java多線程編程實例,分享了幾則多線程的實例代碼,具有一定參考價值,加深多線程編程的理解還是很有幫助的,需要的朋

JavaMail 發微軟郵箱終于成功了

package org.jeecgframework; import com.

夯實基礎系列一:Java 基礎總結

前言 大學期間接觸 Java 的時間也不短了,不論

關于java中Pattern.compile函數的相關解釋

Pattern.compile函數:Pattern Pattern.compile(String regex, int flag)flag的取值范圍如下:Pattern.CANON_EQ,當且僅當兩個字符的"

(責任編輯:jjjccc)

關鍵詞:Java,java,監聽器

福彩3d字谜画谜藏机图