现在的位置: 首页 > 综合 > 正文

servlet_Filter和Listener

2017年12月28日 ⁄ 综合 ⁄ 共 6455字 ⁄ 字号 评论关闭

---Filter

创建一个servlet的Filter步骤:
1)创建Filter处理类
2)在web.xml中通过配置文件配置Filter
或:在Filter类中通过Annotation配置Filter

创建Filter类要实现javax.servlet.Filter接口,Filter接口定义了以下方法:
1.init(FilterConfig filterConfig)由Web容器调用,初始化此Filter。
2.destory()由Web容器调用,初始化此Filter。
3.doFilter(ServletRequest request,ServletResponse response,FilterChain chain)具体过滤处理代码。

--demo1:

//web.xml
	<filter>
		<filter-name>log</filter-name>
		<filter-class>test.LogFilter</filter-class> 
	</filter>
	<filter-mapping>
		<filter-name>log</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
//Filter处理类
package test;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.*;
//@WebFilter(filterName="log", urlPatterns={"/*"})
public class LogFilter implements Filter 
{
	//FilterConfig可用于访问Filter的配置信息
	private FilterConfig config;
	//实现初始化方法
	public void init(FilterConfig config)
	{
		this.config = config; 
	}
	//实现销毁方法
	public void destroy()
	{
		this.config = null; 
	}
	//执行过滤的核心方法
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
		throws IOException,ServletException
	{		
		ServletContext context = this.config.getServletContext();//获取ServletContext对象,用于记录日志 
		long before = System.currentTimeMillis();
		System.out.println("开始过滤...");		
		HttpServletRequest hrequest = (HttpServletRequest)request;//将请求转换成HttpServletRequest请求		
		System.out.println("Filter已经截获到用户的请求的地址: " + hrequest.getServletPath());
		chain.doFilter(request, response); //控制请求是否被放行		
		System.out.println("过滤结束");		
		long after = System.currentTimeMillis();		
		System.out.println("请求被定位到" + hrequest.getRequestURI() + ",所花的时间为: " + (after - before)); 
	} 
}

--demo2:

//web.xml
	<!-- 定义Filter -->
	<filter>
		<filter-name>authority</filter-name>
		<filter-class>test.AuthorityFilter</filter-class>
		<!-- 下面三个init-param元素配置了三个参数 -->
		<init-param>
			<param-name>encoding</param-name>
			<param-value>GBK</param-value>
		</init-param>
		<init-param>
			<param-name>loginPage</param-name>
			<param-value>/login.jsp</param-value>
		</init-param>
		<init-param>
			<param-name>proLogin</param-name>
			<param-value>/proLogin.jsp</param-value>
		</init-param>
	</filter>
	<!-- 定义Filter拦截的URL地址 -->
	<filter-mapping>
		<filter-name>authority</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
//Filter处理类
package test;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;

import java.io.*;

@WebFilter(filterName="authority"
	, urlPatterns={"/*"}
	, initParams={
		@WebInitParam(name="encoding", value="GBK"),
		@WebInitParam(name="loginPage", value="/login.jsp"),
		@WebInitParam(name="proLogin", value="/proLogin.jsp")})
public class AuthorityFilter implements Filter 
{
	//FilterConfig可用于访问Filter的配置信息
	private FilterConfig config;
	//实现初始化方法
	public void init(FilterConfig config)
	{
		this.config = config; 
	}
	//实现销毁方法
	public void destroy()
	{
		this.config = null; 
	}
	//执行过滤的核心方法
	public void doFilter(ServletRequest request,
		ServletResponse response, FilterChain chain)
		throws IOException,ServletException
	{
		//获取该Filter的配置参数
		String encoding = config.getInitParameter("encoding");
		String loginPage = config.getInitParameter("loginPage");
		String proLogin = config.getInitParameter("proLogin");
		//设置request编码用的字符集
		request.setCharacterEncoding(encoding);			
		HttpServletRequest requ = (HttpServletRequest)request;
		HttpSession session = requ.getSession(true);
		//获取客户请求的页面
		String requestPath = requ.getServletPath();
		//如果session范围的user为null,即表明没有登录
		//且用户请求的既不是登录页面,也不是处理登录的页面
		if( session.getAttribute("user") == null
			&& !requestPath.endsWith(loginPage)
			&& !requestPath.endsWith(proLogin))
		{
			//forward到登录页面
			request.setAttribute("tip" , "您还没有登录");
			request.getRequestDispatcher(loginPage)
				.forward(request, response);
		}
		//"放行"请求
		else
		{
			chain.doFilter(request, response);
		}
	} 
}

附:

@WebFilter修饰一个Filter类,用于对Filter进行配置,它支持如下属性:

属    性

是否必需

说    明

asyncSupported

指定该Filter是否支持异步操作模式。

关于Filter的异步调用请参考2.15节

dispatcherTypes

指定该Filter仅对那种dispatcher模式的

请求进行过滤。该属性支持ASYNC、

ERROR、FORWARD、INCLUDE、REQUEST

这5个值的任意组合。默认值为同时

过滤5种模式的请求

displayName

指定该Filter的显示名

filterName

 

指定该Filter的名称

initParams

用于为该Filter配置参数

servletNames

该属性值可指定多个Servlet的名称,

用于指定该Filter仅对这几个Servlet执行过滤

urlPatterns/value 

这两个属性的作用完全相同。都指

定该Filter所拦截的URL

---Listener

Servlet API提供大量监听器来监听Web应用的内部事件,从而允许当Web内部事件发生时回调事件监听器内的方法。

使用Listener步骤:

1)定义Listener实现类

2)通过web.xml文件或Annotation注解配置Listener。如

//方式一;

         使用@WebListener修饰Listener实现类MyListener.java

//方式二:

         在web.xml文件中配置:

         <listener>

                   <listener-class>test.MyListener</listener-class>

         </listener>

        

---常用的listener

链接:http://blog.csdn.net/will_awoke/article/details/8820297

当Web应用在Web容器中运行时,Web应用内部会不断地发生各种事件:如Web应用被启动、Web应用被停止,用户session开始、用户session结束,用户请求到达等,通常来说这些Web事件对开发者是透明的。

常用的Web事件监听器接口有如下几个。

①  ServletContextListener:用于监听Web应用的启动和关闭

监听器类需要实现javax.servlet.ServletContextListener接口,实现:

         contextInitialized(ServletContextEventsce):启动Web应用时,系统调用Listener的该方法

         contextDestroyed(ServletContextEventsce):关闭Web应用时,系统调用Listener的该方法

         ServletContextListener的作用有点类似于load-on-startupServlet,都可以用于在Web应用启动时,回调方法来启动某些后台程序,这些后台程序负责为系统运行提供支持

② ServletContextAttributeListener:用于监听ServletContext范围(application)内属性的改变

监听器类需要实现ServletContextAttributeListener接口,实现:

         attributeAdded(ServletContextAttributeEventevent);当程序把一个属性存入application范围时触发该方法。

         attributeRemoved(ServletContextAttributeEventevent);当程序把一个属性从application范围删除时触发该方法。

         attributeReplaced(ServletContextAttributeEventevent);当程序替换application范围内的属性时触发该方法。

③  ServletRequestListener:用于监听用户请求

监听器类需要实现ServletRequestListener接口,实现:

         requestInitialized(ServletRequestEventsre):用户请求到达、被初始化时触发该方法

         requestDestroyed(ServletRequestEventsre):用户请求结束、被销毁时触发该方法       

④ ServletRequestAttributeListener:用于监听ServletRequest范围(request)内属性的改变。

监听器类需要实现ServletRequestAttributeListener接口,实现:

         attributeAdded(ServletRequestAttributeEventevent);当程序把一个属性存入request范围时触发该方法。

         attributeRemoved(ServletRequestAttributeEventevent);当程序把一个属性从v范围删除时触发该方法。

         attributeReplaced(ServletRequestAttributeEventevent);当程序替换request范围内的属性时触发该方法。

⑤  HttpSessionListener:用于监听用户session的开始和结束

监听器类需要实现HttpSessionListener接口,实现:

         sessionInitialized(HttpSessionEventsre):用户请求到达、被初始化时触发该方法

         sessionDestroyed(HttpSessionEventsre):用户请求结束、被销毁时触发该方法      

⑥  HttpSessionAttributeListener:用于监听HttpSession范围(session)内属性的改变

监听器类需要实现HttpSessionAttributeListener接口,实现:

         attributeAdded(HttpSessionAttributeEventevent);当程序把一个属性存入request范围时触发该方法。

         attributeRemoved(HttpSessionAttributeEventevent);当程序把一个属性从v范围删除时触发该方法。

         attributeReplaced(HttpSessionAttributeEventevent);当程序替换request范围内的属性时触发该方法。

 

---web.xml中的listenerfilterservlet加载顺序

链接:http://zhxing.iteye.com/blog/399668

由此,可以看出,web.xml 的加载顺序是:context-param -> listener -> filter -> servlet ,

而同个类型之间的实际程序调用的时候的顺序是根据对应的 mapping 的顺序进行调用的。

注:摘自轻量级JavaEE企业应用实战第三版

抱歉!评论已关闭.