Filter过滤器与listener监听器的简单使用

Filter过滤器是一种对客户端访问的过滤技术,简单来说就是我们浏览器访问服务器文件时,如果设置了特定的过滤配置,则会先经过过滤器,然后再将请求放给服务器去执行,最常见的就是我们过滤用户是否登录的使用。

listener监听器,见名得意,他就是起到一个监听的作用,主要是用来监听web应用的创建和销毁,以及他们attribute的创建、移除和更新等。 当然也包括用来监听session、request的生命周期以及他们attribute的动态。

一:Filter过滤器

这里我们以过滤器验证用户是否登录为例,进行解释。

首先完整的使用Filter我们需要在web.xml中配置filter的相关信息,告诉服务器我要过滤什么请求还是所有请求都过滤。然后映射到过滤器的类文件中。

 	<filter>
		<filter-name>FirstFilter</filter-name>
		<filter-class>FirstFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>FirstFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

这里配置的是过滤所有请求,当然也可以针对有一个或者某一类请求进行过滤。例如*.mml那所有的.mml结尾的请求都会过滤到过滤器中去处理。

2. 然后新建FirstFilter类文件,需要实现Filter接口,并重写该接口的三个方法。

执行销毁方法:destory()、

执行过滤操作的方法:doFilter()、

初始化方法:init()。

其中doFilter()方法使我们过滤器执行实际过滤过程的方法,我们的实际业务逻辑就是写在这个方法里面的。该方法中有三个参数。

init()方法是过滤器的初始化方法,他跟servlet的init方法不一样,servlet需要配置自启动才会随着tomcat的启动执行init方法。二Filter的init方法一定会随着tomcat的启动而执行该方法的。

在这里我们通过该过滤器打印出一句话,来验证当我们请求时,会执行过滤器操作。代码如下:


//拦截器与servlet的执行顺序,当访问一个servlet请求时,先对servlet进行实例化、初始化、进入过滤器,
//执行过滤器的过滤,过滤器放行之后,再执行servlet的service方法。
public class FirstFilter implements Filter {

	@Override
	public void destroy() {
		
	}

	//执行拦截的方法
	@Override
	public void doFilter(ServletRequest req, ServletResponse res,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;
		String url = request.getRequestURI().toString();
		System.out.printf("访问了 %s%n",url);
		request.setCharacterEncoding("UTF-8");		 
		chain.doFilter(request, response);
	}

	//拦截器的init初始化方法一定会随着tomcat的启动而启动,不需要配置
	@Override
	public void init(FilterConfig arg0) throws ServletException {
	}

}

因为doFilter方法中的参数是servletRequest类型的,我们先把参数转化成HttpServletRequest类型的,然后获取到请求的URL,打印在控制台。通过chain.doFilter(request,response)这个方法,放行该请求,他就可以访问服务器上的资源了。代表着过滤器完成了过滤。

此时我们启动tomcat,请求一个地址,就会看到控制台上打印了我们输出的URL地址。

这就是简单使用过滤器的过程,下面我们在doFilter方法中加入验证登录的过滤逻辑。

3. 验证用户是否登录,我们的核心思想就是

用户打开浏览器访问该网址(此时服务器自动创建一个session对象),当用户登录并验证成功之后,会在session中创建一个key为login的值为"yes"的键值对,

然后如果用户请求的是login.jsp或者login结尾的登录页面,过滤器放行。否则就判断session存在login的值是否为空,如果为空,说明用户没有登录过,就跳转到登录页面,如果不为空,则放行。代码如下:

先是login的servlet验证:如果验证成功,就session中存一个键值对。

public class Login extends HttpServlet {

	public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException {
		
		if("root".equals(request.getParameter("userName")) && "root".equals(request.getParameter("password"))) {
			request.getSession().setAttribute("user", request.getParameter("userName"));
			response.sendRedirect("heroList");
		}else {
			response.sendRedirect("login.html");
		}
	}
}

然后是Filter过滤器的逻辑:

public class FirstFilter implements Filter {
	//执行拦截的方法
	@Override
	public void doFilter(ServletRequest req, ServletResponse res,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;
		String url = request.getRequestURI().toString();
		System.out.printf("访问了 %s%n",url);
		request.setCharacterEncoding("UTF-8");
		
		if(url.endsWith("login.html") || url.endsWith("login")) {
			chain.doFilter(request, response);
			return;
		}
		
		String isUser = (String)request.getSession().getAttribute("user");
		if(null == isUser || "" == isUser) {
			response.sendRedirect("login.html");
			return;
		}
		 
		chain.doFilter(request, response);
	}

}

这样设置完成之后,我们打开浏览器,如果先访问heroList请求,则过滤器没有获取到session中的值,会调到登录页面,直到我们登录验证通过了,session中才会存入值,才会通过过滤器的已经登录的验证。

二:listener监听器:

1. 首先也需要在web.xml中告诉服务器设置了监听类:

	<listener>
		<listener-class>listener.OnlineNumberListener</listener-class>
		<listener-class>listener.RequestListener</listener-class>
		<listener-class>listener.SessionListener</listener-class>
		<listener-class>listener.SessionListenerAttrute</listener-class>
	</listener>

2. 首先新建RequseListener用来监听request的生命周期和attribute的动态。代码如下:如果创建了reques对象就会执行该类中的对应的方法(相当于发起一次请求,就会执行该方法,因为request对象是请求对象,每重新发起请求都会创建一个request),创建attribute也一样。

package listener;

import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;

public class RequestListener implements ServletRequestListener, ServletRequestAttributeListener {

	@Override
	public void attributeAdded(ServletRequestAttributeEvent arg0) {
		System.out.println("创建了attribute:");
		System.out.println("name:"+arg0.getName());
		System.out.println("value:"+arg0.getValue());
	}

	@Override
	public void attributeRemoved(ServletRequestAttributeEvent arg0) {
		syso:监听attribute的移除
	}

	@Override
	public void attributeReplaced(ServletRequestAttributeEvent arg0) {
		syso:监听attribute的替换
	}

	@Override
	public void requestDestroyed(ServletRequestEvent arg0) {
		syso:监听request的销毁
	}

	@Override
	public void requestInitialized(ServletRequestEvent arg0) {
		System.out.println("创建了Request");
	}

}

3. 新建SessionListener、SessionListenerAttrute类监听session和attribute的动态,因为session比较特殊,需要用两个监听器分别来监听。代码如下:

public class SessionListener implements HttpSessionListener {

	@Override
	public void sessionCreated(HttpSessionEvent arg0) {
		System.out.println("监听到session创建:Id是"+arg0.getSession().getId());
	}

	@Override
	public void sessionDestroyed(HttpSessionEvent arg0) {
		
	}

}
public class SessionListenerAttrute implements HttpSessionAttributeListener {

	@Override
	public void attributeAdded(HttpSessionBindingEvent arg0) {
		System.out.println("监听到创建了session的attribute,是:"+arg0.getName()+arg0.getValue());
	}

	@Override
	public void attributeRemoved(HttpSessionBindingEvent arg0) {
		System.out.println("******************退出了登录***********************");
	}

	@Override
	public void attributeReplaced(HttpSessionBindingEvent arg0) {
		
	}

}

使用session的创建和销毁可以模糊的统计在线人数,因为打开浏览器访问页面,就会创建session,也就是一次会话,就相当于一个在线人数,可以用作粗略统计。

感谢阅读!

猜你喜欢

转载自blog.csdn.net/qq_41908550/article/details/83419861