監聽器Listener
jservlet規范包括三個技術點:servlet ;listener ;filter;監聽器就是監聽某個對象的的狀態變化的組件。監聽器的相關概念事件源:
- 被監聽的對象(三個域對象 request,session,servletContext)
- 監聽器:監聽事件源對象, 事件源對象的狀態的變化都會觸發監聽器 。
- 注冊監聽器:將監聽器與事件源進行綁定。
- 響應行為:監聽器監聽到事件源的狀態變化時,所涉及的功能代碼(程序員編寫代碼)
按照被監聽的對象划分:ServletRequest域 ;HttpSession域 ;ServletContext域。按照監聽的內容分:監聽域對象的創建與銷毀的; 監聽域對象的屬性變化的。

三大域對象的創建與銷毀的監聽器
ServletContextListener
監聽ServletContext域的創建與銷毀的監聽器,Servlet域的生命周期:在服務器啟動創建,服務器關閉時銷毀;監聽器的編寫步驟:
- 編寫一個監聽器類去實現監聽器接口
- 覆蓋監聽器的方法
- 需要在web.xml中進行配置(注冊)
1、監聽的方法:

2、配置文件:

ServletContextListener監聽器的主要作用:
- 初始化的工作:初始化對象;初始化數據。比如加載數據庫驅動,對連接池的初始化。
- 加載一些初始化的配置文件;比如spring的配置文件。
- 任務調度(定時器Timer/TimerTask)
例子:MyServletContextListener.java
package com.itheima.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{ @Override //監聽context域對象的創建 public void contextInitialized(ServletContextEvent sce) { //就是被監聽的對象---ServletContext //ServletContext servletContext = sce.getServletContext(); //getSource就是被監聽的對象 是通用的方法 //ServletContext source = (ServletContext) sce.getSource(); //System.out.println("context創建了...."); //開啟一個計息任務調度----每天晚上12點 計息一次 //Timer timer = new Timer(); //task:任務 firstTime:第一次執行時間 period:間隔執行時間 //timer.scheduleAtFixedRate(task, firstTime, period); /*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 = "2016-08-19 00:00:00"; String currentTime = "2016-08-18 09:34:00"; Date parse = null; try { parse = format.parse(currentTime); } catch (ParseException e) { e.printStackTrace(); } timer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { System.out.println("銀行計息了....."); } } , parse, 24*60*60*1000);*/ } //監聽context域對象的銷毀 @Override public void contextDestroyed(ServletContextEvent sce) { System.out.println("context銷毀了...."); } }
web.xml
<listener> <listener-class>com.itheima.attribute.MyServletContextAttributeListener</listener-class> </listener>
HttpSessionListener
監聽Httpsession域的創建與銷毀的監聽器。HttpSession對象的生命周期:第一次調用request.getSession時創建;銷毀有以下幾種情況(服務器關閉、session過期、 手動銷毀)
1、HttpSessionListener的方法
package listener; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; /** * Created by yang on 2017/7/27. */ public class listenerDemo implements HttpSessionListener { @Override public void sessionCreated(HttpSessionEvent httpSessionEvent) { System.out.println("session創建"+httpSessionEvent.getSession().getId()); } @Override public void sessionDestroyed(HttpSessionEvent httpSessionEvent) { System.out.println("session銷毀"); } }
web.xml:
<listener> <listener-class>listener.listenerDemo</listener-class> </listener>
創建session代碼:
package session; import cn.dsna.util.images.ValidateCode; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * Created by yang on 2017/7/24. */ public class SessionDemo extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException { //1 生成驗證碼 ValidateCode code = new ValidateCode(200, 80, 4, 100); //2 將驗證碼保存到session中 System.out.println(code.getCode()); request.getSession().setAttribute("code", code.getCode()); //3 將驗證碼圖片輸出到 瀏覽器 resp.setContentType("image/jpeg"); code.write(resp.getOutputStream()); } }
當創建session時,監聽器中的代碼將執行。
ServletRequestListener
監聽ServletRequest域創建與銷毀的監聽器。ServletRequest的生命周期:每一次請求都會創建request,請求結束則銷毀。
1、ServletRequestListener的方法
package listener; import javax.servlet.ServletRequestEvent; import javax.servlet.ServletRequestListener; /** * Created by yang on 2017/7/27. */ public class RequestListenerDemo implements ServletRequestListener { @Override public void requestDestroyed(ServletRequestEvent servletRequestEvent) { System.out.println("request被銷毀了"); } @Override public void requestInitialized(ServletRequestEvent servletRequestEvent) { System.out.println("request被創建了"); } }
web.xml
<listener> <listener-class>listener.RequestListenerDemo</listener-class> </listener>
只要客戶端發起請求,監聽器中的代碼就會被執行。
監聽三大域對象的屬性變化的
域對象的通用的方法
setAttribute(name,value)
- 觸發添加屬性的監聽器的方法
- 觸發修改屬性的監聽器的方法
getAttribute(name)
removeAttribute(name):觸發刪除屬性的監聽器的方法
ServletContextAttibuteListener監聽器
package listener; import javax.servlet.ServletContextAttributeEvent; import javax.servlet.ServletContextAttributeListener; /** * Created by yang on 2017/7/27. */ public class ServletContextAttrDemo implements ServletContextAttributeListener { @Override public void attributeAdded(ServletContextAttributeEvent scab) { //放到域中的屬性 System.out.println(scab.getName());//放到域中的name System.out.println(scab.getValue());//放到域中的value } @Override public void attributeRemoved(ServletContextAttributeEvent scab) { System.out.println(scab.getName());//刪除的域中的name System.out.println(scab.getValue());//刪除的域中的value } @Override public void attributeReplaced(ServletContextAttributeEvent scab) { System.out.println(scab.getName());//獲得修改前的name System.out.println(scab.getValue());//獲得修改前的value } }
web.xml
<listener> <listener-class>listener.ServletContextAttrDemo</listener-class> </listener>
測試代碼:
package listener; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * Created by yang on 2017/7/27. */ public class ListenerTest extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context=getServletContext(); context.setAttribute("aaa","bbb"); context.setAttribute("aaa","ccc"); context.removeAttribute("aaa"); doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } }
HttpSessionAttributeListener監聽器(同上)
ServletRequestAriibuteListenr監聽器(同上)
與session中的綁定的對象相關的監聽器(對象感知監聽器)
將要被綁定到session中的對象有幾種狀態
- 綁定狀態:就一個對象被放到session域中
- 解綁狀態:就是這個對象從session域中移除了
- 鈍化狀態:是將session內存中的對象持久化(序列化)到磁盤
- 活化狀態:就是將磁盤上的對象再次恢復到session內存中
對象感知監聽器不用在web.xml中配置。
面試題:當用戶很對時,怎樣對服務器進行優化?
綁定與解綁的監聽器HttpSessionBindingListener
package listener; 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被解綁了"); } }
測試類:
package listener; 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 { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession(); //將person對象綁到session中 Person p = new Person(); p.setId("100"); p.setName("zhangsanfeng"); session.setAttribute("person", p); //將person對象從session中解綁 session.removeAttribute("person"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
鈍化與活化的監聽器HttpSessionActivationListener
package listener; 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被活化了"); } }
測試鈍化類:
package listener; 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 { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession(); //將customer放到session中 Customer customer =new Customer(); customer.setId("200"); customer.setName("lucy"); session.setAttribute("customer", customer); System.out.println("customer被放到session域中了"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
當訪問TestCustomerActiveServlet 之后,停止服務器,就會被鈍化,鈍化的文件存在tomcat的work文件加下。
活化類:
package listener; 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 { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //從session域中獲得customer HttpSession session = request.getSession(); Customer customer = (Customer) session.getAttribute("customer"); System.out.println(customer.getName()); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
服務器再次啟動,訪問TestCustomerActiveServlet2之后,就會被活化。可以通過配置文件,指定對象鈍化時間(對象多長時間不用被鈍化)
在META-INF下創建一個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">
<Store className="org.apache.catalina.session.FileStore" directory="itheima32" />
</Manager>
</Context>
郵箱服務器
郵件的客戶端:可以只安裝在電腦上的也可以是網頁形式的;郵件服務器:起到郵件的接受與推送的作用
郵件發送的協議:
協議:就是數據傳輸的約束。接受郵件的協議:POP3 IMAP;發送郵件的協議:SMTP

郵箱的發送過程

郵箱服務器的安裝
雙擊郵箱服務器軟件

對郵箱服務器進行配置





郵箱客戶端的安裝




郵件發送代碼
package com.itheima.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");//發郵件的協議 props.setProperty("mail.host", "localhost");//發送郵件的服務器地址 props.setProperty("mail.smtp.auth", "true");// 指定驗證為true // 創建驗證器 Authenticator auth = new Authenticator() { public PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication("tom", "12345");//發郵件的賬號的驗證 } }; Session session = Session.getInstance(props, auth); // 2.創建一個Message,它相當於是郵件內容 Message message = new MimeMessage(session); message.setFrom(new InternetAddress("tom@itheima32.com")); // 設置發送者 message.setRecipient(RecipientType.TO, new InternetAddress(email)); // 設置發送方式與接收者 message.setSubject(subject);//郵件的主題 message.setContent(emailMsg, "text/html;charset=utf-8"); // 3.創建 Transport用於將郵件發送 Transport.send(message); } }
測試代碼:
package com.itheima.mail; import javax.mail.MessagingException; import javax.mail.internet.AddressException; public class SendMailTest { public static void main(String[] args) throws AddressException, MessagingException { MailUtils.sendMail("lucy@itheima32.com", "測試郵件","這是一封測試郵件"); } }
