JavaWeb學習筆記八 監聽器


監聽器Listener

jservlet規范包括三個技術點:servlet ;listener ;filter;監聽器就是監聽某個對象的的狀態變化的組件。監聽器的相關概念事件源:

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

按照被監聽的對象划分:ServletRequest域 ;HttpSession域 ;ServletContext域。按照監聽的內容分:監聽域對象的創建與銷毀的; 監聽域對象的屬性變化的。

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

ServletContextListener

監聽ServletContext域的創建與銷毀的監聽器,Servlet域的生命周期:在服務器啟動創建,服務器關閉時銷毀;監聽器的編寫步驟:

  • 編寫一個監聽器類去實現監聽器接口
  • 覆蓋監聽器的方法
  • 需要在web.xml中進行配置(注冊)

1、監聽的方法:

 

2、配置文件:

 

ServletContextListener監聽器的主要作用:

  1. 初始化的工作:初始化對象;初始化數據。比如加載數據庫驅動,對連接池的初始化。
  2. 加載一些初始化的配置文件;比如spring的配置文件。
  3. 任務調度(定時器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", "測試郵件","這是一封測試郵件");
    }
    
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM