`

Jsp/Servlet复习笔记-----第5章 过滤器和事件监听器

阅读更多
5.1.1 概念
过滤器(filter)是能够对请求和响应的头属性(header)和能容体(body)进行操作的特殊Web构件。与一般Web构件(如servlet,JSP)不同的是,过滤器自身并不直接生成Web响应,若干个过滤器可以依次对一个Web资源的请求和响应进行作用。
过滤器取代了早先的Servlet链接的功能。更主要的是,过滤器是Servlet2.3版本之后的标准Web构件。它的使用方法比较方便,功能也相当强。如图5-1所示,过滤器可以在Web请求到达servlet(或JSP)之前和在servlet返回响应之后对二者进行操作。过滤器和servlet之间是多对多的关系,一个过滤器可以对多个servlet的请求和响应进行过滤(如Filter A),一个servlet也可以被多个过滤器作用(如servlet3被Filter B,C,D过滤器链过滤)。




过滤器的主要功能包括:
* 对Web请求进行分析,对输入数据进行预处理
* 阻止请求和响应的进行;
* 根据功能改动请求的头信息和数据体;
* 根据功能改动响应的头信息和数据体;
* 和其他Web资源协作。
* 对用户请求进行统一认证;
* 对用户发送的数据进行过滤或替换;
* 对用户的访问进行记录和审核;
读者可能会提出一个问题:这些功能在servlet中都可以实现。确实。前面讲到的servlet API 能够对Web请求和响应进行各种各样的操作,而过滤器的主要意义是提供了一种更方便高效的编程结构。对于许多servlet都需要的功能,使用过滤器独立实现会简化servlet,避免功能重复。另外,Web容器提供了方便的过滤器管理机制,可以让编程人员更轻松地编写Web程序。
可见过滤器程序的特点是通用性和可移植性。如果一个过滤器在程序中只能用在一个servlet或JSP上面而不能被其他Web程序借用,这个过滤器的存在就没有太大意义。通常的过滤器可以用在多种情况下,比如安全保护、运行记录、图像转化、数据压缩、加密解码以及XML转化等。
5.1.2 过滤器的使用
Servlet技术中有关过滤器的API包括javax.servlet包中的Filter,FilterChain和FilterConfig接口。
过滤器要实现javax.servlet.Filter接口。与servlet相似,Filter接口中有init(),destroy()方法。Init方法在初始化时做准备工作,destroy方法在它被Web容器清除之前完成收尾工作,主要的过滤功能在doFilter方法中实现。
程序5.1是javax.servlet.Filter接口的源代码:
package javax.servlet;

import java.io.IOException;

public interface Filter {
	public void init(FilterConfig filterConfig) throws ServletException;
	
    public void doFilter ( ServletRequest request, ServletResponse response, FilterChain chain )
		throws IOException, ServletException;

	public void destroy();
}

程序 5.1
5.1.3 如何使用过滤器实现职责链模式
5.1.4 如何使用过滤器实现装饰器(decrator)设计模式
5.1.5 用MyEclipse开发过滤器使用的例子
登陆验证:
package org.sky.darkness.filter ;

import java.io.* ;
import javax.servlet.* ;
import javax.servlet.http.* ;

public class LoginFilter implements Filter
{
	public void init(FilterConfig filterConfig) throws ServletException{}
	public void doFilter(ServletRequest request,
                     ServletResponse response,
                     FilterChain chain)
              throws IOException,
                     ServletException
	{
		// Session属于HTTP范畴,所以ServletRequest对象需要先转换成HttpServletRequest对象
		HttpServletRequest req = (HttpServletRequest)request ;
		HttpSession session = req.getSession() ;
		// 如果session不为空,则可以浏览其他页面
		if(session.getAttribute("uname")!=null)
		{
			chain.doFilter(request,response) ;
		}
		else
		{
			// 通过requestDispatcher跳转到登陆页
			request.getRequestDispatcher("login.jsp").forward(request,response) ;
		}
	}
	public void destroy() {}
};
/*
  <filter>
	<filter-name>login</filter-name>
	<filter-class> org.sky.darkness.filter.LoginFilter</filter-class>
  </filter>
  <filter-mapping>
	<filter-name>login</filter-name>
	<url-pattern>/*</url-pattern>
  </filter-mapping>

Servlet程序的主要分类?
 标准Servlet(JSP)-MVC
 过滤Servlet(过滤器)
 监听Servlet(监听器)

过滤器在WEB中主要起什么作用:
1. 过滤器是程序运行之后加入的
2. 功能:
 任何网站都需要对用户是否登陆进行过滤
 网上聊天系统,屏蔽非法文字
 对请求内容进行统一编码
写一个Filter类都必须继承(implements) Filter接口
public void init(FilterConfig filterConfig)
          throws ServletException
过滤器初始化是在容器启动时自动初始化的
public void doFilter(ServletRequest request,
                     ServletResponse response,
                     FilterChain chain)
              throws java.io.IOException,
                     ServletException

public void destroy()

package org.sky.darkness.filter ;

import java.io.* ;
import javax.servlet.* ;

public class FirstFilter implements Filter
{
	public void init(FilterConfig filterConfig)
          throws ServletException
	{
		System.out.println("** 过滤器初始化...") ;
	}
	public void doFilter(ServletRequest request,
                     ServletResponse response,
                     FilterChain chain)
              throws IOException,
                     ServletException
	{
		System.out.println("** 过滤器 doFilter (chain之前)...") ;
		chain.doFilter(request,response) ;
		System.out.println("** 过滤器 doFilter (chain之后)...") ;
	}
	public void destroy()
	{
		System.out.println("** 过滤器销毁...") ;
	}
};
/*
  <filter>
	<filter-name>first</filter-name>
	<filter-class> org.sky.darkness.filter.FirstFilter</filter-class>
  </filter>
  <filter-mapping>
	<filter-name>first</filter-name>
	<url-pattern>/*</url-pattern>
  </filter-mapping>
*/

xml文件中的配置:
<filter>
   <filter-name> first </filter-name>
   <filter-class> org.sky.darkness.filter.FirstFilter</filter-class>
</filter>
<filter-mapping>
   <filter-name> first </filter-name>
   <url-pattern>/*</url-pattern>//与servlet的不一样,此处表示对哪个页面进行过滤
</filter-mapping>
  

如果过滤器要将内容传递到目的地,则需要FilterChain,将请求继续向下转发chain.doFilter(request, response)

过滤器执行两次,chain之前执行一次,chain之后执行一次
1.过滤非法文字:
	string content = request.getParameter(“content”);
    if(content != null){
if(content.indexOf(“AAA”)==-1)chain.doFilter(req,res);
else  out .println(“有非法文字!!!”);
   }else chain.doFilter(req,res);

package org.sky.darkness.filter ;

import java.io.* ;
import javax.servlet.* ;

public class CharFilter implements Filter
{
	public void init(FilterConfig filterConfig)
          throws ServletException
	{
		// System.out.println("** 过滤器初始化...") ;
	}
	public void doFilter(ServletRequest request,
                     ServletResponse response,
                     FilterChain chain)
              throws IOException,
                     ServletException
	{
		String content = request.getParameter("content") ;
		// 如果indexOf返回-1则表示没有查到所要的内容
		if(content!=null)
		{
			if(content.indexOf("AAA")==-1)
			{
				chain.doFilter(request,response) ;
			}
			else
			{
				System.out.println("有非法文字") ;
				// 如果需要的话,此处依然可以使用RequestDispatcher进行跳转
			}	
		}
		else
		{
			chain.doFilter(request,response) ;
		}
	}
	public void destroy()
	{
		// System.out.println("** 过滤器销毁...") ;
	}
};
/*
  <filter>
	<filter-name>char</filter-name>
	<filter-class>org.sky.darkness.filter.CharFilter</filter-class>
  </filter>
  <filter-mapping>
	<filter-name>char</filter-name>
	<url-pattern>/*</url-pattern>
  </filter-mapping>
*/

2. 进行统一编码
  request.setCharacterEncoding(“gb2312”)

package org.sky.darkness.filter ;

import java.io.* ;
import javax.servlet.* ;

public class EncodingFilter implements Filter
{
	public void init(FilterConfig filterConfig)
          throws ServletException
	{
		// System.out.println("** 过滤器初始化...") ;
	}
	public void doFilter(ServletRequest request,
                     ServletResponse response,
                     FilterChain chain)
              throws IOException,
                     ServletException
	{
		try
		{
			request.setCharacterEncoding("GB2312") ;	
		}
		catch (Exception e)
		{
		}
		
		chain.doFilter(request,response) ;
	}
	public void destroy()
	{
		// System.out.println("** 过滤器销毁...") ;
	}
};
/*
  <filter>
	<filter-name>encoding</filter-name>
	<filter-class> org.sky.darkness.filter.EncodingFilter</filter-class>
  </filter>
  <filter-mapping>
	<filter-name>encoding</filter-name>
	<url-pattern>/*</url-pattern>
  </filter-mapping>
*/

3.登陆验证
   Session属于HTTP范畴,所以ServletRequset对象需要先转换为 HttpServletRequest对象
   HttpServletRequest req = (HttpServletRequest)req;
   HttpSession session = req.getSession();
   if(session.getAttribute(“uname”) != null)
       chain.doFilter(req,res);
   else
       request.getRequestDispatcher(“login.jsp”).forward(req,res);

package org.sky.darkness.filter ;

import java.io.* ;
import javax.servlet.* ;
import javax.servlet.http.* ;

public class LoginFilter implements Filter
{
	public void init(FilterConfig filterConfig)
          throws ServletException
	{
		// System.out.println("** 过滤器初始化...") ;
	}
	public void doFilter(ServletRequest request,
                     ServletResponse response,
                     FilterChain chain)
              throws IOException,
                     ServletException
	{
		// Session属于HTTP范畴,所以ServletRequest对象需要先转换成HttpServletRequest对象
		HttpServletRequest req = (HttpServletRequest)request ;
		HttpSession session = req.getSession() ;
		// 如果session不为空,则可以浏览其他页面
		if(session.getAttribute("uname")!=null)
		{
			chain.doFilter(request,response) ;
		}
		else
		{
			// 通过requestDispatcher跳转到登陆页
			request.getRequestDispatcher("login.jsp").forward(request,response) ;
		}
	}
	public void destroy()
	{
		// System.out.println("** 过滤器销毁...") ;
	}
};
/*
  <filter>
	<filter-name>login</filter-name>
	<filter-class> org.sky.darkness.filter.LoginFilter</filter-class>
  </filter>
  <filter-mapping>
	<filter-name>login</filter-name>
	<url-pattern>/*</url-pattern>
  </filter-mapping>
*/


原则:开发时只专注于具体的业务实现,而对于登陆之类的验证,肯定属于组件,向整个程序中单独加入的。


监听器
5.2.1概念  
5.2.2 事件监听器的使用
5.2.3 MyEclipse开发事件监听器使用的例子
监听器是指对于整个WEB环境的监听
主要有以下三类:
 ServletContext:Servlet上下文
 Session:对Session监听
 Request监听

一、 对ServletContext的监听
在web端实现监听 = 实现一系列的监听接口
1、 ServletContextListener:对整个 servlet上下文进行监听(启动,销毁)
public void contextInitialized(ServletContextEvent sce):上下文初始化
public void contextDestroyed(ServletContextEvent sce):上下文销毁

ServletContextEvent事件:取得一个ServletContext (Applicaton)对象
public ServletContext getServletContext()
2、 ServletContextAttributeListener:对Servlet上下文属性进行监听
public void attributeAdded(ServletContextAttributeEvent scab):增加属性(setAttribute)
public void attributeRemoved(ServletContextAttributeEvent scab) :属性删除(removeAttribute)
public void attributeReplaced(ServletContextAttributeEvent scab):属性替换(第二次设置同一个属性)

ServletContextAttributeEvent事件:
public java.lang.String getName()
public java.lang.Object getValue()

回顾: 设置属性的方法
    Public void setAttribute (String name ,Object  value)
package org.sky.darkness.listener ;

import javax.servlet.* ;

public class ServletContextDemo
	implements ServletContextListener,ServletContextAttributeListener
{
	private ServletContext application = null ;
	// 实现方法
	public void contextInitialized(ServletContextEvent sce)
	{
		this.application = sce.getServletContext() ;
		System.out.println("** 上下文初始化 ...") ;
		System.out.println("** 当前虚拟目录的绝对路径:"+this.application.getRealPath("/")) ;
	}
	public void contextDestroyed(ServletContextEvent sce)
	{
		System.out.println("** 上下文销毁 ...") ;
	}

	public void attributeAdded(ServletContextAttributeEvent scab)
	{
		System.out.println("** 增加属性:"+scab.getName()+" --> "+scab.getValue()) ;
	}
	public void attributeRemoved(ServletContextAttributeEvent scab)
	{
		System.out.println("** 删除属性:"+scab.getName()+" --> "+scab.getValue()) ;
	}
	public void attributeReplaced(ServletContextAttributeEvent scab)
	{
		System.out.println("** 替换属性:"+scab.getName()+" --> "+scab.getValue()) ;
	}
};

/*
  <listener>
	<listener-class> org.sky.darkness.listener.ServletContextDemo</listener-class>
  </listener>
*/

<!--测试页面-->
<%
	// getServletContext().setAttribute("name","LiXingHua") ;
	getServletContext().removeAttribute("name") ;
%>

上下文监听主要是针对容器的:初始化、销毁、属性操作
二、 对Session监听

对session的创建、销毁、属性操作

Session属于http协议下的内容:javax.servlet.http.HttpSessionXxxx
1、 HttpSessionListener:对session的整体状况的监听
public void sessionCreated(HttpSessionEvent se)
public void sessionDestroyed(HttpSessionEvent se):session销毁

HttpSessionEvent事件:
public HttpSession getSession():取得当前操作的 session
2、 HttpSessionAttributeListener

public void attributeAdded(HttpSessionBindingEvent se)
public void attributeRemoved(HttpSessionBindingEvent se)
public void attributeReplaced(HttpSessionBindingEvent se)

HttpSessionBindingEvent事件:
public HttpSession getSession():取得当前的Session
public java.lang.String getName():取得属性的名称
public java.lang.Object getValue()
package org.sky.darkness.listener ;

import javax.servlet.http.* ;

public class HttpSessionDemo 
	implements HttpSessionListener,HttpSessionAttributeListener
{
	private HttpSession session ;
	// 实现方法
	public void sessionCreated(HttpSessionEvent se)
	{
		this.session = se.getSession() ;
		System.out.println("** Session 创建 ....") ;
		System.out.println("** SessionID --> "+this.session.getId()) ;
	}
	public void sessionDestroyed(HttpSessionEvent se)
	{
		System.out.println("** Session 销毁 ....") ;
	}
	public void attributeAdded(HttpSessionBindingEvent se)
	{
		System.out.println("** Session 增加属性:"+se.getName()+" --> "+se.getValue()) ;
	}
	public void attributeRemoved(HttpSessionBindingEvent se)
	{
		System.out.println("** Session 删除属性:"+se.getName()+" --> "+se.getValue()) ;
	}
	public void attributeReplaced(HttpSessionBindingEvent se)
	{
		System.out.println("** Session 替换属性:"+se.getName()+" --> "+se.getValue()) ;
	}
};
/*
  <listener>
	<listener-class> org.sky.darkness.listener.HttpSessionDemo</listener-class>
  </listener>
*/

<%
	// session.setAttribute("name","LXh") ;
	// session.removeAttribute("name") ;
	session.invalidate() ;
%>

Session如何销毁?
1、 session超时
需要在xml文件中进行配置
<session-config>
<session-timetout>1</session-timeout>//session一分钟失效
</session-config>
2、 手工使session失效
Invalidate()

案例:
统计在线人员列表
实现那几个接口?
1、 在线人员列表是对所有人都起作用,所有的数据必须保存在application之中,这意味着在OnlineDemo中必须有一个ServletContext对象
2、 是针对session的变化进行的操作
如果登陆成功,则将用户名保存在session中
3、 如果用户注销,则将相应的用户名删除掉

因为用户名是多个,所以无法确定个数,使用list
package org.sky.darkness.listener ;

import java.util.* ;
import javax.servlet.* ;
import javax.servlet.http.* ;

public class OnLineDemo 
	implements ServletContextListener,HttpSessionListener,HttpSessionAttributeListener
{
	// 声明一个ServletContext对象
	private ServletContext application = null ;
	public void contextInitialized(ServletContextEvent sce)
	{
		// 容器初始化时,向application中存放一个空的容器
		this.application = sce.getServletContext() ;
		this.application.setAttribute("alluser",new ArrayList()) ;
	}

	public void contextDestroyed(ServletContextEvent sce)
	{}

	public void sessionCreated(HttpSessionEvent se)
	{}
	public void sessionDestroyed(HttpSessionEvent se)
	{
		// 将用户名称从列表中删除
		List l = (List)this.application.getAttribute("alluser") ;
		String value = (String)se.getSession().getAttribute("uname") ;
		l.remove(value) ;
		this.application.setAttribute("alluser",l) ;
	}

	public void attributeAdded(HttpSessionBindingEvent se)
	{
		// 如果登陆成功,则将用户名保存在列表之中
		List l = (List)this.application.getAttribute("alluser") ;
		l.add(se.getValue()) ;
		this.application.setAttribute("alluser",l) ;
	}
	public void attributeRemoved(HttpSessionBindingEvent se)
	{}
	public void attributeReplaced(HttpSessionBindingEvent se)
	{}
};
/*
  <listener>
	<listener-class>cn.mldn.lxh.listener.OnLineDemo</listener-class>
  </listener>
*/

<%@ page contentType="text/html;charset=gb2312"%>
<%@ page import="java.util.*"%>
<form action="online.jsp" method="post">
用户名:
<input type="text" name="name">
<input type="submit" value="登陆">
<a href="logout.jsp">注销</a>
</form>
<!-- 向session接收输入的用户名 -->
<%
	if(request.getParameter("name")!=null)
	{
		session.setAttribute("uname",request.getParameter("name")) ;
	}
%>
<h2>在线人员</h2>
<hr>
<%
	List l = (List)application.getAttribute("alluser") ;
	Iterator iter = l.iterator() ;
	while(iter.hasNext())
	{
%>
		<li><%=iter.next()%>
<%
	}
%>
-------------------------------------------------------logout.jsp-------------------
<%
	session.invalidate() ;
%>



  • 大小: 25.2 KB
分享到:
评论

相关推荐

    jsp/servlet个人学习笔记

    在 `web.xml` 文件中,开发者可以配置 JSP 页面、Servlet、过滤器和监听器的行为,以及定义 URL 映射、错误处理等。它是整个 Web 应用的配置中心。 9. **常见错误** 在 JSP 和 Servlet 开发中,常见的错误包括...

    林学良Jsp&Servlet学习笔记

    在实际学习过程中,你可能还会涉及到Web容器的概念、部署描述符(web.xml)、请求和响应对象的使用、会话管理、Cookie、过滤器和监听器等进阶话题。通过不断实践和理解,你将能够熟练掌握这两种技术,为构建复杂的...

    JSP&Servlet学习笔记.pdf

    在学习JSP和Servlet时,经常会涉及到一些重要的概念和知识点,例如:会话管理(session管理)、请求分发(request dispatcher)、过滤器(filter)、监听器(listener)、JSP标准标签库(JSTL)以及表达式语言(EL)...

    JSP Servlet 学习笔记源码

    过滤器在Servlet容器中拦截请求和响应,可以进行预处理和后处理,比如登录验证、字符编码转换等。监听器则监听特定事件,如会话创建、销毁,ServletContext的改变等,实现相应的逻辑。 7. **部署和运行**: JSP和...

    JSP&Servlet学习笔记(第2版)_打印版

    5. **过滤器和监听器**:Servlet框架支持过滤器和监听器,这些工具可以帮助开发者在不同的级别对请求和响应进行预处理或后处理。 ### 实际应用场景 1. **用户登录验证**:Servlet可以用来处理用户的登录请求,并...

    JSP-Servlet学习笔记第2版.pdf

    10. JSP和Servlet的高级特性:比如会话跟踪、cookie处理、过滤器、监听器、MVC模式等。 11. 实际开发中遇到的问题及其解决方案:例如,处理请求中文乱码问题、在开发中如何分层以及代码的组织和管理。 以上就是...

    Jsp_Servlet学习课堂笔记

    6. **监听器(Listener)**:可以监听特定事件,如会话创建、销毁,或者ServletContext的初始化和销毁,实现特定的功能。 **JavaBean**是符合JavaBeans规范的Java类,通常作为可重用的组件使用,它们可以在JSP和...

    韩顺平笔记 java jsp servlet

    "韩顺平servlet笔记(8讲)"可能讲解了Servlet生命周期、请求和响应对象、过滤器和监听器等核心概念。通过学习Servlet,你可以理解Web应用的后端逻辑,并能有效地处理用户请求。 这三者结合,构成了一套完整的Java ...

    15_尚硅谷_Filter过滤器_王振国 - 课堂笔记1

    Filter 过滤器是 JavaWeb 的三大组件之一,另外两个组件是 Servlet 程序和 Listener 监听器。Filter 过滤器是一个接口,它的作用是拦截请求,过滤响应。常见的应用场景有权限检查、日记操作、事务管理等等。 ...

    Servlet&JSP学习笔记源代码

    9. **过滤器(Filter)和监听器(Listener)**:学习如何实现Filter接口和ServletContextListener接口,增强应用的功能和可维护性。 10. **部署与运行**:在Eclipse中配置Tomcat服务器,理解war文件的打包和部署...

    第一个Servlet程序的源码以及视频的笔记

    总的来说,"第一个Servlet程序"的学习涵盖了Java Web开发的基本步骤,为后续的JSP、过滤器、监听器等高级概念奠定了基础。通过深入学习和实践,你可以更好地理解和应用Servlet,构建动态、交互式的Web应用程序。

    Servlet&JSP;学习笔记源代码

    Servlet和JSP是Java Web开发中的核心技术,广泛用于构建动态网站和Web应用程序。这份"Servlet&JSP学习笔记源代码"是由林信良编著,提供了丰富的实例代码,旨在帮助学习者深入理解这两种技术。 Servlet是Java编程...

    jsp自制详细笔记

    【描述】提到"详细的jsp和servlet资料",这意味着文件内容可能包括了JSP的基本语法、指令、动作元素、内置对象、EL表达式以及Servlet的生命周期、服务方法、过滤器和监听器等基础知识。这些资料对初学者来说非常重要...

    jsd1906 达内 07-Servlet.rar

    在传统的Servlet配置中,`web.xml`文件是必不可少的,它定义了Servlet的映射路径、初始化参数、过滤器和监听器等。例如,以下代码创建了一个名为"MyServlet"的Servlet: ```xml &lt;servlet&gt; &lt;servlet-name&gt;My...

    JSP Servlet笔记 (by金万林)

    `web.xml`是Web应用的部署描述符,用于配置Servlet、过滤器、监听器、会话超时、安全约束等。`*`通配符用于匹配多个元素,但其优先级需要根据具体配置规则理解。 ### 开发调试技巧 1. **显示URL列表** - 开发期间...

    jsp学习笔记

    - 部署描述器是Web应用程序的配置文件,定义了Servlet的映射、过滤器、监听器和其他元数据。 - 在`web.xml`中,你可以指定Servlet的URL模式,初始化参数,以及其他配置信息。 7. **打包与部署** - 将Servlets和...

    韩顺平servlet笔记

    7. **web.xml**:部署描述符,定义了Servlet的映射、过滤器、监听器等配置,是Servlet容器解析和初始化Servlet的重要依据。 通过韩顺平的servlet笔记,读者不仅可以学习到Servlet编程的基本技能,还能掌握Tomcat...

    B站韩顺平2011最细servlet笔记全

    8. **监听器Listener**:Servlet容器中的事件监听器,可以监听Servlet上下文、session和request事件,如监听session的创建和销毁,或者监听某个属性的变化。 9. **MVC模式与Servlet**:虽然Servlet本身不直接支持...

    javaweb 学习笔记

    - 映射 Servlet: `&lt;servlet-mapping&gt;&lt;servlet-name&gt;MyServlet&lt;/servlet-name&gt;&lt;url-pattern&gt;/myservlet&lt;/url-pattern&gt;&lt;/servlet-mapping&gt;` - 配置监听器: `&lt;listener&gt;&lt;listener-class&gt;...

Global site tag (gtag.js) - Google Analytics