JavaWeb中监听器+过滤器+拦截器区别、配置和实际应用
1. JavaWeb中监听器+过滤器+拦截器 https://blog.csdn.net/Jintao_Ma/article/details/52972482
1.前沿上一篇文章提到在web.xml中各个元素的执行顺序是这样的,context-param-->listener-->filter-->servlet; 而拦截器是在Spring MVC中配置的,如果从整个项目中看,一个servlet请求的执行过程就变成了这样context-param-->listener-->filter-->servlet-->interceptor(指的是拦截器),为什么拦截器是在servlet执行之后,因为拦截器本身就是在servlet内部的,下面把所学和所总结的用自己的描述整理出来~。另外本文的项目框架是基于上篇文章http://blog.csdn.net/Jintao_Ma/article/details/52892625 讲述的框架,下载路径:http://download.csdn.net/download/jintao_ma/9661038。
2.概念
context-param:就是一些需要初始化的配置,放入context-param中,从而被监听器(这里特指org.springframework.web.context.ContextLoaderListener)监听,然后加载;
监听器(listener):就是对项目起到监听的作用,它能感知到包括request(请求域),session(会话域)和applicaiton(应用程序)的初始化和属性的变化;
过滤器(filter):就是对请求起到过滤的作用,它在监听器之后,作用在servlet之前,对请求进行过滤;
servlet:就是对request和response进行处理的容器,它在filter之后执行,servlet其中的一部分就是controller层(标记为servlet_2),还包括渲染视图层(标记为servlet_3)和进入controller之前系统的一些处理部分(servlet_1),另外我们把servlet开始的时刻标记为servlet_0,servlet结束的时刻标记为servlet_4。
拦截器(interceptor):就是对请求和返回进行拦截,它作用在servlet的内部,具体来说有三个地方:
1)servlet_1和servlet_2之间,即请求还没有到controller层
2)servlet_2和servlet_3之间,即请求走出controller层次,还没有到渲染时图层
3)servlet_3和servlet_4之间,即结束视图渲染,但是还没有到servlet的结束
它们之间的关系,可以用一张图来表示:
3.使用原则
对整个流程清楚之后,然后就是各自的使用,在使用之前应该有一个使用规则,为什么这个说,因为有些功能比如判断用户是否登录,既可以用过滤器,也可以用拦截器,用哪一个才是合理的呢?那么如果有一个原则,使用起来就会更加合理。实际上这个原则是有的:
把整个项目的流程比作一条河,那么监听器的作用就是能够听到河流里的所有声音,过滤器就是能够过滤出其中的鱼,而拦截器则是拦截其中的部分鱼,并且作标记。所以当需要监听到项目中的一些信息,并且不需要对流程做更改时,用监听器;当需要过滤掉其中的部分信息,只留一部分时,就用过滤器;当需要对其流程进行更改,做相关的记录时用拦截器。下面是具体的使用案例
本文涉及到的jsp页面:
index.jsp:
<%@ page language="java" import="com.mycompany.mvc.listener.*" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>index.jsp</title> </head> <body> this is index jsp <!-- 这里应该填入用户名和密码 --> <a href="/myWebApp/system/login">login</a> <br></br> 测试servletcontext: <% application.setAttribute("app","app"); application.getAttribute("app"); application.removeAttribute("app"); %> <br></br> 测试httpsession: <% session.setAttribute("app3","app3"); session.getAttribute("app3"); session.removeAttribute("app3"); %> <br></br> 测试servletrequest: <% request.setAttribute("app3","app3"); request.getAttribute("app3"); request.removeAttribute("app3"); %> <br></br> 当前在线人数: <%=session.getAttribute("peopleOnLine")%> <br></br> HttpSessionBindingListener测试: <% session.setAttribute("bean",new myHttpSessionBindingListener()); session.removeAttribute("bean"); %> </body> </html>
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>main.jsp</title> </head> <c:set var="ctx" value="${pageContext.request.scheme}://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}" /> <script type="text/javascript" src="${ctx}/plugins/jquery-3.0.0/jquery-3.0.0.js"></script> <script type="text/javascript"> </script> <body> This is has login jsp <a href="/myWebApp/system/view">view</a> </body> </html>
view.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>view jsp</title> </head> <body> 用户已经登陆,欢迎来到登陆后系统主界面 </body> </html>
4.监听器
4.1listener具体分为八种,能够监听包括request域,session域,application域的产生,销毁和属性的变化;
具体使用,可以看之前转载一篇文章(再次感谢"孤傲苍狼",他的主页http://www.cnblogs.com/xdp-gacl/):http://blog.csdn.net/Jintao_Ma/article/details/51464124
在配置完然后我们在web.xml中诸如下面的配置即可:
<listener> <listener-class> com.mycompany.mvc.listener.myServletContextListener </listener-class> </listener> <listener> <listener-class> com.mycompany.mvc.listener.myServletContextAttributeListener </listener-class> </listener>
4.2 listener实际应用
4.2.1 获取当前在线人数
package com.mycompany.mvc.listener; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; public class myHttpSessionListener implements HttpSessionListener{ public static int peopleOnLine = 0; @Override public void sessionCreated(HttpSessionEvent arg0) { System.out.println("myHttpSessionListener.sessionCreated():"+arg0); peopleOnLine++; arg0.getSession().setAttribute("peopleOnLine",peopleOnLine); } @Override public void sessionDestroyed(HttpSessionEvent arg0) { System.out.println("myHttpSessionListener.sessionDestroyed():"+arg0); peopleOnLine--; arg0.getSession().setAttribute("peopleOnLine",peopleOnLine); } }
在页面中就可以获取:
当前在线人数: <%=session.getAttribute("peopleOnLine")%>
其实也可以获得历史所有在线人数,只需要把历史所有在线人数保存在文件中,然后每次项目启动读取这个文件,当前人数增加时,把历史所有人数也相应增加,项目关闭时,再保存起来。
4.2.2 在系统初始化时,获取项目绝对路径
如下,获得绝对路径后保存到系统变量System中:
@Override public void contextInitialized(ServletContextEvent servletContext) { System.out.println("myServletContextListener.contextInitialized()"); System.setProperty("realPath", servletContext.getServletContext().getRealPath("/")); System.out.println("myServletContextListener.contextInitialized()"); }
5.过滤器(filter)
5.1过滤器只需要继承javax.servlet.filter即可,一般来说我们只要添加tomcat运行时环境就能够包含javax.servlet的jar包,但是eclipse在tomcat8中没有找到,实际上tomcat8中确实没有,只有通过maven来添加了:
<!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <!-- https://mvnrepository.com/artifact/javax.servlet/jsp-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> </dependency>
5.2 filter的实际应用
5.2.1 请求编码转换
package com.mycompany.mvc.filter; import java.io.IOException; import java.util.HashMap; import java.util.Map; 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 org.slf4j.Logger; import org.slf4j.LoggerFactory; public class urlEncodeFilter implements Filter{ Logger logger = LoggerFactory.getLogger(urlEncodeFilter.class); Map<String,Object> paramMap = new HashMap<String,Object>(); @Override public void destroy() { } @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { System.out.println("urlEncodeFilter doFilter..."+paramMap.get("urlEncode").toString()); arg0.setCharacterEncoding(paramMap.get("urlEncode").toString()); arg2.doFilter(arg0, arg1); } @Override public void init(FilterConfig arg0) throws ServletException { String urlEncode = arg0.getInitParameter("urlEncode"); paramMap.put("urlEncode",urlEncode); } }
web.xml配置:
<filter> <filter-name>urlEncodeFilter</filter-name> <filter-class>com.mycompany.mvc.filter.urlEncodeFilter</filter-class> <init-param> <param-name>urlEncode</param-name> <param-value>UTF-8</param-value> </init-param> </filter>
<filter-mapping> <filter-name>urlEncodeFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
5.2.2 日志记录,比如记录所有对网站发起请求的地址
package com.mycompany.mvc.filter; 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.HttpServletRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class logFilter implements Filter{ Logger logger = LoggerFactory.getLogger(logFilter.class); @Override public void destroy() { } @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest)arg0; System.out.println("logFilter doFilter servletPath:"+request.getRemoteHost()); arg2.doFilter(arg0, arg1); } @Override public void init(FilterConfig arg0) throws ServletException { } }
web.xml:
<filter> <filter-name>logFilter</filter-name> <filter-class>com.mycompany.mvc.filter.logFilter</filter-class> </filter>
<filter-mapping> <filter-name>logFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
5.2.3 对未登陆用户的判断
package com.mycompany.mvc.filter; 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.HttpServletRequest; import javax.servlet.http.HttpSession; import org.apache.commons.lang.StringUtils; import com.mycompany.mvc.utils.Constant; public class loginFilter implements Filter{ private String dispatchUrl = ""; private String excludeUrl = ""; @Override public void destroy() { } @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest)arg0; String servletPath = request.getServletPath(); HttpSession session = request.getSession(); String sessionKey = (String) session.getAttribute(Constant.SESSIONKEY); /*就是登陆界面不进行过滤*/ if(servletPath.equals(dispatchUrl) || servletPath.equals(excludeUrl)){ arg2.doFilter(arg0, arg1); }else{ if(!StringUtils.isEmpty(sessionKey)){ arg2.doFilter(arg0, arg1); }else{ request.getRequestDispatcher(dispatchUrl).forward(arg0, arg1); } } } @Override public void init(FilterConfig arg0) throws ServletException { dispatchUrl = arg0.getInitParameter("dispatchUrl"); excludeUrl = arg0.getInitParameter("excludeUrl"); } }
web.xml:
<filter> <filter-name>loginFilter</filter-name> <filter-class>com.mycompany.mvc.filter.loginFilter</filter-class> <init-param> <!-- 不进行过滤的url,因为它就是跳转到登陆界面, --> <param-name>excludeUrl</param-name> <param-value>/main</param-value> </init-param> <init-param> <!-- 未登录用户跳转的url --> <param-name>dispatchUrl</param-name> <param-value>/system/login</param-value> </init-param> </filter>
<filter-mapping> <filter-name>loginFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
之所以上面的/main能够直接跳转到index这个登陆界面,是因为SpringMvc中配置了这个(上篇文章有讲述到):
<mvc:view-controller path="${adminPath}" view-name="index"/>
它的意思就是不经过controller层,直接把index放入ModelAndView,然后由渲染层进行渲染。 讲到这里,再结合上面说到的拦截器,我们发现,这个时候拦截器还是能够拦截2次的,就是视图渲染前和渲染后,但是进入controller层之前肯定拦截不到了,因为请求根本就没有进入controller。
相关推荐
### JavaWeb中的监听器与过滤器 #### 一、监听器(Listener) 监听器是Java Web应用程序中的一个重要组件,主要用于监听容器中特定事件的发生,并作出相应的反应。在Java Web开发中,监听器主要用来监控应用中某些...
在`<filter-mapping>`标签内,我们可以配置多种过滤器拦截规则,如: 1. **URL模式匹配**:完全匹配(如`/hello`)、目录匹配(如`/admin/*`)和扩展名匹配(如`*.jsp`)。 2. **Servlet名称匹配**:当过滤的目标是...
过滤器(Filter)可以在请求到达目标资源之前或之后对其进行拦截,进行预处理或后处理,例如认证、编码转换等。监听器(Listener)则可以监听特定事件,如session创建、销毁或用户登录事件,执行相应的逻辑。 8. *...
在IT行业中,监听器(Listener)和过滤器(Filter)是两种非常重要的组件,它们在Web应用程序中扮演着不可或缺的角色。本文将详细讲解如何利用监听器进行访问计数以及通过过滤器来过滤非法字符,以确保系统的安全性...
Struts2 拦截器是JavaWeb开发中Struts2框架的核心组件之一,它基于AOP(面向切面编程)理念,允许开发者在Action方法执行前后插入自定义逻辑。拦截器与Servlet中的过滤器虽然在功能上有相似之处,但它们在设计和使用...
JavaWeb技术是构建基于Java平台的Web应用程序的重要框架,它包括了Servlet、JSP、EL表达式、JSTL标签库、Filter过滤器以及Listener监听器等多个关键组件。这些组件协同工作,使得开发者能够创建动态、交互式的Web...
在JavaWeb开发中,过滤器(Filter)是一个非常重要的组件,它允许我们在HTTP请求和响应之间进行拦截,执行一些预处理或后处理操作。这里我们将深入探讨标题中提到的几个常用的过滤器及其源码实现。 首先,我们来看...
4. **Filter(过滤器)**: 过滤器在JavaWeb中用于拦截和处理请求与响应,如权限控制、字符编码转换等。案例中会展示如何定义和配置Filter,以及如何在多个Filter之间进行链式调用。 5. **Listener(监听器)**: ...
监听器是JavaWeb中的事件监听组件,用于监听特定的Web容器事件。常见的监听器包括HttpSessionListener、ServletRequestListener、ServletContextListener,它们可以在特定事件发生时执行相应的操作,如session创建、...
在JavaWeb中,Servlet和Filter是两个核心组件,而监听器(Listener)则提供了更高级的功能,帮助开发者管理和监控应用状态。这个"JavaWeb Servlet过滤监听应用.zip"文件包含了关于如何在实际项目中运用这些概念的...
6. **过滤器(Filter)**:在JavaWEB应用中,过滤器可以拦截请求和响应,进行预处理或后处理。常见的用途包括登录验证、字符编码转换、日志记录等。通过实现`Filter`接口并配置在web.xml中,可以定义多个过滤器并...
Filter和Listener可以用来做请求的拦截和监听,以实现过滤器链和事件监听等高级功能。 【文件名称列表】中的"StudentDrom.iml"是IntelliJ IDEA项目配置文件,表明该项目是在IDEA环境下开发的。".idea"目录包含了...
6. **过滤器(Filter)与监听器(Listener)**:这两者是JavaWeb中的重要组件,过滤器可以拦截请求和响应,实现预处理和后处理功能,如字符编码转换;监听器则可以监听特定事件,如session的创建和销毁。 7. **Web...
8. **过滤器和监听器**:过滤器(Filter)用于拦截和处理请求,监听器(Listener)用于监听特定事件。源代码可能包含过滤器和监听器的实现,如字符编码过滤器、登录验证过滤器和会话监听器。 9. **部署描述符**:`...
6. **过滤器与监听器**:Filter和Listener是JavaWeb的重要组件。过滤器可以拦截请求和响应,进行预处理或后处理,如字符编码转换。监听器监听特定的事件,如session的创建、销毁,实现特定功能。 7. **Apache ...
5. **Filter(过滤器)**:过滤器在JavaWeb中用于拦截请求和响应,实现预处理和后处理功能,如登录验证、数据编码解码等。了解过滤器的生命周期、配置以及如何编写自定义过滤器是必要的。 6. **Listener(监听器)*...
5. **过滤器(Filter)**: 在JavaWeb中,过滤器可以拦截HTTP请求和响应,进行预处理或后处理。例如,登录检查、字符编码转换、日志记录等都可以通过过滤器实现。 6. **监听器(Listener)**: 监听器接口跟踪特定的...
除此之外,过滤器(Filter)和监听器(Listener)也是JavaWeb的重要组件。过滤器可以对HTTP请求和响应进行拦截,实现如登录检查、字符编码转换等功能。监听器则用于监听Web应用中的特定事件,例如会话创建或销毁,...
8. **过滤器与监听器**:Filter和Listener是JavaWeb中增强功能的组件。过滤器可以对请求和响应进行拦截处理,监听器则用于监听特定的Web事件。 9. **会话管理**:理解如何在JavaWeb中创建、跟踪和管理用户的会话,...
JavaWeb开发主要涉及Servlet、JSP、JSTL、过滤器、监听器、MVC设计模式以及相关的框架如Spring MVC和Struts等。 1. **Servlet**:Servlet是Java平台上的服务器端程序,主要用于扩展服务器的功能,处理HTTP请求。在...