1. 程式人生 > >Java Listener學習

Java Listener學習

共有8個類
生命週期 tomcat啟動後建立 tomcat關閉後銷燬

物件名稱 監聽事件
ServletContextListener ServletContext域物件的建立與銷燬
HttpSessionListener Session域物件的建立與銷燬
ServletRequestListener Request域物件的建立與銷燬
ServletContextAttributeListener ServletContext域物件的屬性改變時
HttpSessionAttributeListener Session域物件的屬性改變時
ServletRequestAttributeListener Request域物件的屬性改變時
HttpSessionBindingListener 被繫結到session中的物件新增或刪除後觸發
HttpSessionActivationListener session中的物件活化鈍化後觸發
<!--把Listener註冊到web.xml中-->
<listener>
  	<listener-class>com.java.TestListener</listener-class>
  </listener>
//ServletContextListene示例
public class TestListener implements ServletContextListener {
	@Override
	public void contextInitialized(ServletContextEvent sce)
{ Object source = sce.getSource();//獲得被監聽的物件(需要強轉使用) ServletContext servletContext = sce.getServletContext();//獲得被監聽的物件 System.out.println("ServletContext域建立 - - -"); } @Override public void contextDestroyed(ServletContextEvent sce) { System.out.println("ServletContext域銷燬 - - -"); } }

注意點選此處是關閉java虛擬機器 整個java都關閉不會執行java監聽器方法
在這裡插入圖片描述
點選此處是關閉javaweb程式 可以執行java監聽器方法
在這裡插入圖片描述

private static int i;
public void contextInitialized(ServletContextEvent sce) {
		System.out.println("ServletContext域建立 - - -");
		Timer timer = new Timer();
		//方法引數分別為 TimerTask的實現類物件 開始執行時間 執行間隔時間(毫秒)
		timer.scheduleAtFixedRate(new TimerTask() {
			@Override
			public void run() {
				i++;
				System.out.println("第"+i+"次呼叫");
			}
		}, new Date(), 5000);
	}
//使用listener實現任務排程 明天晚上0點開始執行 一天執行一次
	private static int i;
	@Override
	public void contextInitialized(ServletContextEvent sce) {
		System.out.println("ServletContext域建立 - - -");
		String strTime = "2018-12-18 00:00:00";
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		Date date = null;
		try {
			date = format.parse(strTime);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		
		Timer timer = new Timer();
		timer.scheduleAtFixedRate(new TimerTask() {
			
			@Override
			public void run() {
				i++;
				System.out.println("第"+i+"天呼叫");
			}
		}, date, 1000*60*60*24);
		System.out.println(format);
	}
//HttpSessionListener示例
public class TestListener implements HttpSessionListener {
	@Override
	public void sessionCreated(HttpSessionEvent se) {
		System.out.println("session已建立"+se.getSession().getId());
	}
	@Override
	public void sessionDestroyed(HttpSessionEvent se) {
		System.out.println("session已銷燬");
	}
}
//jsp頁面
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>訪問jsp頁面預設session域物件會自動建立</h1>
</body>
</html>

ServletRequestListener與前兩個域物件類似

域物件都有這三個方法
setAttrbute(name,value)
	--觸發新增屬性的監聽器的方法
	--觸發修改屬性的監聽器的方法
getAttrbute(name)
	--不觸發任何方法
removeAttrbute(name)
	--觸發刪除屬性的監聽器的方法

ServletContextAttributeListener|ServletContext域物件的屬性改變時
HttpSessionAttributeListener|Session域物件的屬性改變時
ServletRequestAttributeListener|Request域物件的屬性改變時
//servlet程式碼
@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		ServletContext context = this.getServletContext();
		//在ServletContext中新增資料
		context.setAttribute("name", "test1");
		//修改ServletContext的資料
		context.setAttribute("name", "test2");
		//刪除ServletContext的資料
		context.removeAttribute("name");
	}
//ServletContextAttributeListener程式碼
public class TestListener implements ServletContextAttributeListener {
	@Override
	public void attributeAdded(ServletContextAttributeEvent scab) {
		String name = scab.getName();//獲取域物件中的name--name
		Object value = scab.getValue();//獲取域物件中的value--test1
	}

	@Override
	public void attributeRemoved(ServletContextAttributeEvent scab) {
		String name = scab.getName();//獲取修改前域物件中的name--name
		Object value = scab.getValue();//獲取修改前域物件中的value--test1
	}

	@Override
	public void attributeReplaced(ServletContextAttributeEvent scab) {
		String name = scab.getName();//刪除域物件中的name--name
		Object value = scab.getValue();//刪除域域物件中的value--test2
	}
}

HttpSessionAttributeListener(與前者域物件類似)
ServletRequestAttributeListener(與前者域物件類似)
session的其他監聽器

//物件感知監聽器 session中的物件繫結與解綁 HttpSessionBindingListener
public class TestJava implements HttpSessionBindingListener{
	private String name;
	private int age;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	//該物件被繫結到session中後觸發
	@Override
	public void valueBound(HttpSessionBindingEvent event) {
		System.out.println("已被session繫結");//即把當前類的物件新增到session域
	}
	//該物件從session中解綁後觸發
	@Override
	public void valueUnbound(HttpSessionBindingEvent event) {
		System.out.println("已被session解綁");//即新增到session域中當前類例項化後的物件
	}
}
//鈍化和活化監聽器 HttpSessionActivationListener 需實現Serializable方可活化
public class TestJava implements HttpSessionActivationListener, Serializable {
	private String name;
	private int age;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	// 該物件活化後呼叫此方法
	public void sessionDidActivate(HttpSessionEvent se) {
		System.out.println("session中物件已活化");
	}

	@Override
	// 該物件鈍化後呼叫此方法
	public void sessionWillPassivate(HttpSessionEvent se) {
		System.out.println("session中物件已鈍化");
	}
}

session持久化

預設tomcat預設開啟session持久化 當tomcat伺服器關閉後會把未銷燬的session鈍化 持久到本地SESSIONS.ser檔案中
再次開啟tomcat時 tomcat會把已經鈍化的session活化(前提是session中的該物件實現Serializable介面)
<!--在WebContent -> META-INF下新建content.xml 以下手動來控制session鈍化和活化-->
<?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="資料夾名" />
	</Manager>
</Context>
//java listener實現定時傳送生日郵件祝福
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 users 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 SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse("2018-12-19 00:00:00"), 1000*10);
		//起始時間是一個固定的時間 間隔時間是1天 1月 1年
	}

	@Override
	public void contextDestroyed(ServletContextEvent sce) {

	}

}