栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【JavaWeb学习】07:Servlet高级

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【JavaWeb学习】07:Servlet高级

第七章:Servlet高级

Filter与Listener是Servlet规范中的两个高级特性,不同于Servlet其不用处理客户端请求。

Filter用于对request、response对象进行修改,Listener用于对context、session、request事件进行监听,善用两个对象。

一、Filter过滤器 1.Filter概念

Filter被称为过滤器,其基本功能是对Servelet容器调用Servlet的过程进行拦截,从而在Servlet进行响应处理前后实现一些特殊功能。

Filter过滤器实现了javax.servlet.Filter接口的类,在javax.servlet.Filter接口中定义了3个方法,如下表:

方法声明说明
init(FilterConfig filterConfig)初始化过滤器
doFilter(ServletRequest request, ServletResponse response, FilterChain chain)参数chain代表当前Filter链的对象
destroy()该方法在web服务器卸载Filter对象之前被调用,用于释放Filter对象打开的资源

注意:如果要用到FilterConfig对象,那么初始化代码就只能在Filter的init()方法中编写,而不能在构造方法中

以上3个方法都是Filter的生命周期方法,init()在web应用程序加载的时候被调用、destroy()在web应用程序卸载时调用:

doFilter()方法只要有客户端请求时就会被调用,并且Filter所有的工作集中在该方法之中。

注意:init()与destroy()方法都只会被调用一次

2.Filter映射

Filter拦截的资源需要在web.xml文件中进行配置,这些配置信息就是Filter映射。

过滤器的配置信息中包含多个元素,这些元素分别具有不同的作用具体如下:

配置信息中元素说明
根元素,用于注册一个Filter
子元素用于设置Filter名称
子元素用于设置Filter类的完整名称
根元素用于设置一个过滤器所拦截的资源
子元素用于匹配用户请求的URL

具体使用如下:

package c8p1;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyServlet extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.getWriter().write("Hello MyServlet");
	}
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}
}
package c8p1;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class MyFilter implements Filter {
	public void init(FilterConfig filterConfig) throws ServletException {
		//1.过滤器对象在初始化时调用,可以配置一些初始化参数
	}
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		//2.用于拦截用户的请求,如果和当前过滤器的拦截路径匹配,该方法就会被调用
		PrintWriter out = response.getWriter();
		out.write("Hello MyFilter");
	}
	public void destroy() {
		//3.过滤器对象在销毁时自动调用,释放资源
	}
}


	
		MyServlet
		c8p1.MyServlet	
	
	
		MyServlet
		/MyServlet
	
	
		MyFilter
		c8p1.MyFilter
	
	
		MyFilter
		/MyFilter
	

注意:上述请求中设置了设置了对/MyServlet请求资源进行拦截,将在请求到达MyServlet程序前执行MyFilter程序。

分析:通过url地址直接访问MyServlet资源没有显示Hello MyServlet,而显示为Hello MyFilter(由于Filter拦截)

(1)拦截全部请求:通配符*

Filter的元素用于配置过滤器拦截的资源信息,使用通配符*来拦截所有的请求访问:


	MyFilter
	c8p1.MyFilter


	MyFilter
	/*

(2)拦截不同方式的访问请求

Filter的元素用于配置过滤器拦截的资源信息,

其子元素用于指定过滤器所拦截的资源被Servlet容器调用的方式,其值共有4个:

case1:REQUEST

当用户直接访问页面时,web容器将会调用过滤器。

若目标资源是通过RequestDispatcher的include()或forward()方法访问的,那么过滤器将不会被调用。

case2:INCLUDE

如果目标资源是通过RequestDispatcher的include()方法访问的,那么过滤器将被调用。

case3:FORWARD

如果目标资源是通过RequestDispatcher的forward()方法访问的,那么过滤器将被调用。

case4:ERROR

如果目标资源是通过声明式异常处理机制调用的,那么过滤器将被调用。

具体使用如下:

package c8p2;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

// ForwardServlet用于将请求转发给first.jsp页面
public class ForwardServlet extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.getRequestDispatcher("/first.jsp").forward(request, response);
	}
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}
}
package c8p2;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

// 该过滤器用于对first.jsp页面的访问进行拦截
public class ForwardFilter implements Filter{
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		// 1.过滤器对象在初始化时调用,可以配置一些初始化参数
	}
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		// 2.用于拦截用户的请求,如果和当前过滤器的拦截路径匹配,该方法会被调用
		PrintWriter out = response.getWriter();
		out.write("Hello FilterTest_FORWARD");
	}
	@Override
	public void destroy() {
		// 3.过滤器对象在销毁时自动调用
	}
}


	
		ForwardServlet
		c8p2.ForwardServlet	
	
	
		ForwardServlet
		/ForwardServlet
	
	
		ForwardFilter
		c8p2.ForwardFilter
	
	
		ForwardFilter
		/first.jsp
        FORWARD
	

分析:通过在web.xml文件中设置了FORWARD后:

当目标资源通过RequestDispatcher的forward()方法访问时,Filter过滤器将被调用。(first.jsp的页面内容并没有显示,显示内容为ForwardFilter类中的内容)

3.Filter链

在一个Web应用程序中可以注册多个Filter程序,每个Filter程序都可以针对某个URL进行拦截。

如果多个Filter程序对一个URL进行拦截,那么这些Filter就会组成一个Filter链(过滤器链)。

Filter链用FilterChain对象表示,FilterChain对象有一个doFilter()方法,让Filter链上当前过滤器放行(使请求进入下一个Filter)。

具体使用如下:

package c8p3;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class MyFilter01 implements Filter {
	public void init(FilterConfig filterConfig) throws ServletException {
		//1.过滤器对象在初始化时调用,可以配置一些初始化参数
	}
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		//2.用于拦截用户的请求,如果和当前过滤器的拦截路径匹配,该方法就会被调用
		PrintWriter out = response.getWriter();
		out.write("Hello MyFilter01
"); chain.doFilter(request, response); } public void destroy() { //3.过滤器对象在销毁时自动调用,释放资源 } }
package c8p3;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class MyFilter02 implements Filter {
	public void init(FilterConfig filterConfig) throws ServletException {
		//1.过滤器对象在初始化时调用,可以配置一些初始化参数
	}
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		//2.用于拦截用户的请求,如果和当前过滤器的拦截路径匹配,该方法就会被调用
		PrintWriter out = response.getWriter();
		out.write("Hello MyFilter02 Before
"); chain.doFilter(request, response); out.write("
Hello MyFilter02 After
"); } public void destroy() { //3.过滤器对象在销毁时自动调用,释放资源 } }


	
		MyServlet
		c8p1.MyServlet	
	
	
		MyServlet
		/MyServlet
	
	
		MyFilter01
		c8p3.MyFilter01
	
	
		MyFilter01
		/MyServlet
	
	
		MyFilter02
		c8p2.MyFilter02
	
	
		MyFilter02
		/MyServlet
	

注意:Filter链中各个Filter的拦截顺序与它们在web.xml文件中元素的映射顺序是一致的

分析:在对MyServlet资源进行访问时,首先被MyFilter01拦截(输出其中内容),后被MyFilter02拦截,被放行之后才输出MyServlet中的内容。

⚠️问题:

问题1:上述程序中发现输出的
标签使用chrome浏览器时不被解析,而使用IE浏览器时才能被正常解析

相关解答查询

问题2:为什么MyFilter02 After会被输出显示?

在MyFilter02中,当调用到doFilter()方法时,请求将直接被发送给目标资源(从而out.write("
Hello MyFilter02 After
");)将不被执行?

4.FilterConfig接口

为了获取Filter程序在web.xml文件中的配置信息,Servlet API提供了一个FIiterConfig接口,

该接口封装了Filter程序在web.xml中的所有配置信息,并提供了一系列获取这些配置信息的方法:

方法名说明
String getFilterName()返回在web.xml文件中为Filter设置的名称
String getInitParameter(String name)返回在web.xml文件中为Filter设置的某个名称的初始化参数值
Enumeration getInitParameterNames()返回在web.xml文件中为Filter设置的所有初始化参数的名称
ServletContext getServletContext()返回FilterConfig对象中所包装的ServletContext对象的引用

具体使用如下:

package c8p1;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyServlet extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.getWriter().write("Hello MyServlet");
	}
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}
}
package c8p4;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class MyFilter03 implements Filter {
	private String characterEncoding;
	FilterConfig fc;
	public void init(FilterConfig filterConfig) throws ServletException {
		// 1.获取FilterConfig对象
		this.fc = filterConfig;
	}
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		// 2.输出参数信息
		characterEncoding = fc.getInitParameter("encoding");
		System.out.println("encoding初始化参数的值为:" + characterEncoding);
		chain.doFilter(request, response);
	}
	public void destroy() {
		//3.过滤器对象在销毁时自动调用,释放资源
	}
}


	
	
		MyFilter03
		c8p4.MyFilter03
		
			encoding
			GBK
		
	
	
		MyFilter03
		/MyServlet
	


分析:浏览器窗口中输出了Hello MyServlet,而在控制台窗口输出了encoding的参数信息

5.应用1:Filter实现用户自动登录(存在问题) (1)cookie自动登录:

cookie可以实现用户自动登录功能:

当用户第一次访问服务器时,服务器会发送一个包含用户信息的cookie,

当客户端再次访问服务器时,会向服务器回送cookie,服务器从cookie中获取用户信息,从而实现用户的自动登录功能。

注意:当客户端访问服务器的Servlet时,所有Servlet都需要对用户的cookie信息进行校验(造成代码重复)

可以在Filter程序中实现cookie的检验,简化代码:

由于Filter可以对服务器的所有请求进行拦截,因此一旦通过Filter程序就相当于用户信息通过了校验(Servlet程序根据获取到的用户信息就可以实现自动登录)

(2)Filter简化Cooie自动登录:


step1:User类

注意:使用Filter实现自动登录功能程序还有一定问题,本周之内改善

package c8p5;

public class User {
	private String username;
	private String password;
	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;
	}
}
step2:jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="utf-8"%>


	
		Insert title here
	
	
		

用户登录

用户名:   ${errerMsg}
密 码:   
自动登录时间 一个月 三个月 半年 一年
    
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="utf-8" import="java.util.*" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>


	
		显示登录的用户信息
	
	
		
			
				
				

Please login first

点击登录

Welcome to the site!

欢迎你,${sessionScope.user.username}! 点击注销

step3:Servlet(Login&Logout)
package c8p5;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoginServlet extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 1.获取用户名和密码
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		// 2.检查用户名和密码
		if ("lch".equals(username) && "123456".equals(password)) {
			// 登录成功
			// (1)将用户状态user对象存入session域中
			User user = new User();
			user.setUsername(username);
			user.setPassword(password);
			request.getSession().setAttribute("user", user);
			// (2)获取用户是否登录的标识符autologin,if判断是否发送自动登录的cookie(autoLogin)
			String autologin = request.getParameter("autologin");
			if (autologin != null) {
				// 用户点击了自动登录->将用户信息保存到cookie中(将在AutoLoginFilter中被使用)
				cookie cookie = new cookie("autoLogin", username + "-" + password);
                int time = Integer.parseInt(autologin);
				cookie.setMaxAge(time);
				cookie.setPath(request.getContextPath());
				response.addcookie(cookie);
			}
            // (3)重定向index主页面,回显用户信息
			response.sendRedirect(request.getContextPath() + "/index.jsp");
		} else {
			// 登录失败
            // (1)保存登录失败信息
			request.setAttribute("errerMsg", "用户名或密码错误");
            // (2)重定向login登录页面,回显错误信息
			request.getRequestDispatcher("/login.jsp").forward(request, response);
		}
	}
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}
}
package c8p5;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LogoutServlet extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 1.清除session中保存的用户信息
		request.getSession().removeAttribute("user");
		// 2.清除cookie中保存的用户信息(cookie覆盖)
		cookie cookie = new cookie("autoLogin", "");
        cookie.setMaxAge(0);
		cookie.setPath(request.getContextPath());
		response.addcookie(cookie);
        // 3.重定向到index主页面
		response.sendRedirect(request.getContextPath() + "/index.jsp");
	}
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}
}
step4:Servlet(Filter)
package c8p5;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.cookie;
import javax.servlet.http.HttpServletRequest;

public class AutoLoginFilter implements Filter {
	public void init(FilterConfig filterConfig) throws ServletException {
		// TODO Auto-generated method stub
	}
	public void doFilter(ServletRequest req, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		//类型强转为HttpServletRequest对象之后才有getcookies()方法
		HttpServletRequest request = (HttpServletRequest) req;
		// 1.获取所有的cookie信息
		cookie[] cookies = request.getcookies();
        // 2.遍历cookie,找到保存了用户名与密码的cookie(autoLogin)
		String username_passwd = null;
		for (int i = 0; cookies != null && i < cookies.length; ++i) {
			String cookieName = cookies[i].getName();
			if ("autoLogin".equals(cookieName)) {
				username_passwd = cookies[i].getValue();
				break;
			}
		}
		// 3.如果获取到的用户名与密码不为空,则做自动登录
		if (username_passwd != null) {
			String[] parts = username_passwd.split("-");
			String username = parts[0];
			String password = parts[1];
			// (1)检查用户名和密码,若登录成功则将用户信息user对象存入session域中
			if ("itcast".equals(username) && ("123456").equals(password)) {
				User user = new User();
				user.setUsername(username);
				user.setPassword(password);
				request.getSession().setAttribute("user", user);
			}
		}
		// 3.放行
		chain.doFilter(request, response);
	}
	public void destroy() {
		// TODO Auto-generated method stub
	}
}
step5:xml配置


	
	
		AutoLoginFilter
		c8p5.AutoLoginFilter
	
	
		AutoLoginFilter
		/*
	
	
		LoginServlet
		c8p5.LoginServlet	
	
	
		LoginServlet
		/LoginServlet
	
	
		LogoutServlet
		c8p5.LogoutServlet	
	
	
		LogoutServlet
		/LogoutServlet
	

step6:自动登录检验

根据实验目的:在完成首次登录网站后,在一定时间内将能够直接访问index主页而跳过login界面:

测试1:尝试使用url地址直接访问主页(由于没有cookie登录信息,将显示用户登录超链接)

测试2:尝试正常首次登录首页

测试3:尝试使用url地址直接访问主页(由于已经保存了cookie信息,应自动登录)

注意:如果在首次登录之后点击了注销,则自动登录功能将失效(Logout.servlet删除客户端中的cookie)

6.应用2:Filter实现全站编码统一

在web开发中经常会遇到中文乱码问题,根据之前知识可通过在Servlet程序中设置编码方式解决,

但如果多个Servlet程序都需要设置编码方式,则将导致大量的重复代码(可以在Filter中对获取到的请求和响应消息进行编码),

从而实现全站编码统一。

step1:form.jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="utf-8" import="java.util.*" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>


	
		form.jsp
	
	
		

用户登录

点击超链接进行登录
用户名:   ${errerMsg}
密 码:   
    
step2:Servlet(CharacterServlet)
package c8p6;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CharacterServlet extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println(request.getParameter("name"));
		System.out.println(request.getParameter("password"));
	}
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}
}
step3:Servlet(Filter)
package c8p6;

import java.io.IOException;
import java.io.UnsupportedEncodingException;

import javax.management.RuntimeErrorException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;

public class CharacterFilter implements Filter {
	public void init(FilterConfig arg0) throws ServletException {
		// TODO Auto-generated method stub
		
	}
	public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest)req;
		HttpServletResponse response = (HttpServletResponse)resp;
		// 1.拦截所有请求,处理全站中文乱码
		request.setCharacterEncoding("utf-8"); //只对消息体有效
		response.setContentType("text/html; charset=utf-8");
		// 2.对request进行包装
		CharacterRequest characterRequest = new CharacterRequest(request);
		chain.doFilter(characterRequest, response);
	}
	public void destroy() {
		// TODO Auto-generated method stub
		
	}
}

// 继承 默认包装类HttpServletRequestWrapper
class CharacterRequest extends HttpServletRequestWrapper {
	private HttpServletRequest request;
	public CharacterRequest(HttpServletRequest request) {
		super(request);
		this.request = request;
	}
	// 子类继承父类一定会覆写一些方法,此处用于重写getParamter()方法
	public String getParameter(String name) {
		// 1.调用被包装对象的getParameter()方法,获得请求参数
		String value = super.getParameter(name);
		if (value == null)
			return null;
		// 2.判断请求方式
		String method = super.getMethod();
		if ("get".equalsIgnoreCase(method)) {
			try {
				value = new String(value.getBytes("iso-8859-1"), "utf-8");
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				throw new RuntimeException(e);
			}
		}
		// 3.解决乱码后返回结果
		return value;
	}
}
step4:xml配置


	
	
		CharacterServlet
		c8p6.CharacterServlet	
	
	
		CharacterServlet
		/CharacterServlet
	
	
		CharacterFilter
		c8p6.CharacterFilter
	
	
		CharacterFilter
		/7
	

step5:统一编码测试

POST方式提交测试:在form表单中输入账号与密码信息后,点击提交按钮进行数据提交,查看控制台输出:

GET方式提交测试:在form.jsp页面中直接点击超链接,进行直接登录,查看控制台输出信息:

总结:两次输出结果相同都没有出现乱码问题,说明Filter过滤器快捷的完成了统一编码的功能。

二、Listener监听器 1.Listener监听器概述:

在程序开发中需要对某些事件进行监听,监听器在监听的过程中主要有以下几个部分

  1. 事件(Event):用户的任意一个操作
  2. 事件源:产生事件的对象
  3. 事件监听器(Listener):负责监听发生在事件源上的事件
  4. 事件处理器:监听器的成员方法,当事件发生时会触发对应的处理器(成员方法)

事件处理器在进行工作时,可分为几个步骤具体如下:

步骤说明
step1:注册监听器将监听器绑定到事件源
step2:传递事件对象事件发生时会触发监听器的成员方法(事件处理器)
step3:处理事件源事件处理器通过事件对象获得事件源,并对进行处理

在Web开发中使用的监听器(Servlet事件监听器),就是一个实现了特定接口的Java程序

专门用于监听Web应用程序中ServletContext、HttpSession和ServletRequest等域对象的创建与销毁、监听域对象属性的修改,

及感知HttpSession域中某个对象的状态,具体如下图所示:

注意:HttpSessionActivationListener用于监听HttpSession中对象活化和钝化的过程

Web服务器会根据监听器实现的接口,将其注册到被监听的对象上,

当触发了某个对象的监听事件时,Web容器将会调用Servlet监听器与之相关的方法对事件进行处理。

2.应用1:监听域对象的生命周期:

要对Servlet域对象的生命周期进行监听,

首先要实现域对象对应的ServletContextListener、HttpSessionListener和ServletRequestListener3个接口,

这些接口中的方法和执行过程非常类似,可以为每一个监听器编写一个单独的类,也可以用一个类实现这3个接口(从而让这个类具有3个事件监听器的功能)。

step1:myjsp.jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="utf-8"%>


	
		this is MyJsp.jsp page
	
	
		这是一个测试监听器页面!
	

step2:Listener
package c8p7;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class MyListener implements ServletContextListener, HttpSessionListener, ServletRequestListener {
	public void contextInitialized(ServletContextEvent arg0) {
		System.out.println("ServletContext对象被创建了!");
	}
	public void contextDestroyed(ServletContextEvent arg0) {
		System.out.println("ServletContext对象被销毁了!");
	}
	public void requestInitialized(ServletRequestEvent arg0) {
		System.out.println("ServletRequest对象被创建了!");
	}
	public void requestDestroyed(ServletRequestEvent arg0) {
		System.out.println("ServletRequest对象被销毁了!");
	}
	public void sessionCreated(HttpSessionEvent arg0) {
		System.out.println("HttpSession对象被创建了!");
	}
	public void sessionDestroyed(HttpSessionEvent arg0) {
		System.out.println("HttpSession对象被销毁了!");
	}
}
step3:xml配置

    c8p7.MyListener


    1

step4:生命周期监听测试

在tomcat启动服务器后,通过浏览器访问myjsp.jsp页面,并同时观察eclipse控制台的输出情况如下:

一分钟后,ServletSession对象也被销毁了(调用Destroyed方法)

3.应用2:监听域对象的属性变更:

通过所学监听器知识,读者应学会使用监听器监听域对象的属性变更。

step1:testAttribute.jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="utf-8"%>


	
		testAttribute
	
	
		
这是一个测试对象属性信息监听器的页面
<% getServletContext().setAttribute("username", "lch"); getServletContext().setAttribute("username", "luochenhao"); getServletContext().removeAttribute("username"); session.setAttribute("username", "lch"); session.setAttribute("username", "luochenhao"); session.removeAttribute("username"); request.setAttribute("username", "lch"); request.setAttribute("username", "luochenhao"); request.removeAttribute("username"); %>
step2:Listener
package c8p8;

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;

public class MyAttributeListener implements ServletContextAttributeListener, ServletRequestAttributeListener, HttpSessionAttributeListener {
	// 1.ServletContext属性监听
	public void attributeAdded(ServletContextAttributeEvent sae) {
		String name = sae.getName();
		System.out.println("ServletContext添加属性:" + name + "=" + sae.getServletContext().getAttribute(name));
	}
	public void attributeRemoved(ServletContextAttributeEvent sae) {
		String name = sae.getName();
		System.out.println("ServletContext移除属性:" + name + "=" + name);
	}
	public void attributeReplaced(ServletContextAttributeEvent sae) {
		String name = sae.getName();
		System.out.println("ServletContext替换属性:" + name + "=" + sae.getServletContext().getAttribute(name));
	}
	// 2.HttpSession属性监听
	public void attributeAdded(HttpSessionBindingEvent hbe) {
		String name = hbe.getName();
		System.out.println("HttpSession添加属性:" + name + "=" + hbe.getSession().getAttribute(name));
	}
	public void attributeRemoved(HttpSessionBindingEvent hbe) {
		String name = hbe.getName();
		System.out.println("HttpSession移除属性:" + name);
	}
	public void attributeReplaced(HttpSessionBindingEvent hbe) {
		String name = hbe.getName();
		System.out.println("HttpSession替换属性:" + name + "=" + hbe.getSession().getAttribute(name));
	}
	// 3.ServletRequest属性监听
	public void attributeAdded(ServletRequestAttributeEvent srae) {
		String name = srae.getName();
		System.out.println("ServletRequest添加属性:" + name + "=" + srae.getServletRequest().getAttribute(name));
	}
	public void attributeRemoved(ServletRequestAttributeEvent srae) {
		String name = srae.getName();
		System.out.println("ServletRequest移除属性:" + name);
	}
	public void attributeReplaced(ServletRequestAttributeEvent srae) {
		String name = srae.getName();
		System.out.println("ServletRequest替换属性:" + name + "=" + srae.getServletRequest().getAttribute(name));
	}
}
step3:xml配置

		c8p8.MyAttributeListener

step4:属性监听测试

在tomcat启动服务器后,通过浏览器访问testAttribute.jsp页面,并同时观察eclipse控制台的输出情况如下:


可以看出在三个域对象中,分别完成了属性增加、替换与删除的监听操作

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/572082.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号