过滤器与拦截器_学习笔记
过滤器与拦截器
过滤器(Filter)
过滤器是Java EE中的组件。
过滤器是执行在Servlet之前的组件。
过滤器可以对请求进行过滤,如果不满足自行指定的条件,可以拦截下来,不予放行,请求就不会被Servlet处理。
过滤器也需要在web.xml中配置注册,通常,映射的路径范围较大,因为它通常用于处理多个甚至所有Servlet需要执行的任务。
同一个应用中可以存在多个过滤器,形成“过滤器链”,当某个请求被服务器处理时,会依次执行各个过滤器,只有全部放行,才会被Servlet处理。
1.过滤器的优点
a.可以在不修改源代码的基础上,为应用添加新的功能。
b.可以将多个组件相同的功能集中写在过滤器里面,方便代码的维护。
2.如何写一个过滤器
step1.写一个java类,实现Filter接口。
step2.在doFilter方法里面,实现拦截处理逻辑。
step3.配置过滤器。(web.xml)
<filter> <filter-name>commentFilter2</filter-name> <filter-class>web.CommentFilter2</filter-class> <init-param> <param-name>size</param-name> <param-value>5</param-value> </init-param> </filter> <filter-mapping> <filter-name>commentFilter2</filter-name> <url-pattern>/comment</url-pattern> </filter-mapping> <filter> <filter-name>commentFilter</filter-name> <filter-class>web.CommentFilter</filter-class> </filter> <filter-mapping> <filter-name>commentFilter</filter-name> <url-pattern>/comment</url-pattern> </filter-mapping>
容器启动后会检查配置文件,把里面所以有的过滤器先实例化,将实例化后的对象放到FilterChain对象中(过滤器链),顺序按照优先级存放(配置文件的先后顺序),
package filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import java.io.IOException; @WebFilter(filterName = "CommentFilter",urlPatterns = "/comment") public class CommentFilter implements Filter { /** * 容器启动之后,会立即创建过滤器实例。 * 注: * 只会创建一个实例! */ public CommentFilter() { System.out.println("------------CommentFilter()-------------------"); } /** * 容器在创建好过滤器实例之后,会立即 * 调用该实例的init方法。 * 注: * 该方法只会调用一次! */ public void init(FilterConfig config) throws ServletException { System.out.println("-----------CommentFilter----init()-----------------------"); } /** * 容器在调用完过滤器的init方法之后, * 会调用doFilter方法来处理请求。 * 注:(了解) * ServletRequest是HttpServletRequest * 的父接口,ServletResponse是 * HttpServletResponse的父接口。 * * FilterChain(过滤器链): * 如果调用了该对象的doFilter方法, * 表示继续向后调用;否则,中断请求,返回 * 处理结果。 * */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException { System.out.println("------------commentFileter's doFilter()---------------"); chain.doFilter(request, response); } public void destroy() { } }
控制台输出:
过滤器的配置与Servlet非常相似:
<filter> <filter-name></filter-name> <filter-class></filter-class> </filter> <filter-mapping> <filter-name></filter-name> <url-pattern></url-pattern> </filter-mapping>
拦截器(Interceptor)
1基本概念
拦截器是SpringMVC中的组件,执行时优先于控制器(其实,每个拦截器都会执行3次,1次在控制器之前,2次在控制器之后,通常关注的是在控制器之前执行的那一次)。
2基本使用
step1:写拦截器类
自定义拦截器需要实现
HandlerInterceptor接口,该接口中共3个抽象方法,其中,
preHandle()方法是在控制器之前执行的,可以起到拦截效果,该方法的返回值表示是否拦截,为
true时放行,为
false时拦截。
public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { // 测试输出 System.out.println("LoginInterceptor.preHandle()"); // 拦截规则: // 如果未登录,重定向到登录,并拦截 // 如果已登录,直接放行 HttpSession session = httpServletRequest.getSession(); if (session.getAttribute("username") == null) { httpServletResponse.sendRedirect("../user/login.do"); return false; } return false; } @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { } }
step2:在spring的配置文件中配置拦截器
在spring的配置文件中配置拦截器
<!-- 拦截器链 --> <mvc:interceptors> <!-- 第1个拦截器 --> <mvc:interceptor> <!-- 1. 黑名单 --> <mvc:mapping path="/user/*"/> <!-- 2. 白名单 --> <mvc:exclude-mapping path="/user/reg.do"/> <mvc:exclude-mapping path="/user/login.do"/> <mvc:exclude-mapping path="/user/handle_reg.do"/> <mvc:exclude-mapping path="/user/handle_login.do"/> <!-- 3. 拦截器类 --> <bean class="cn.tedu.spring.LoginInterceptor" /> </mvc:interceptor> </mvc:interceptors>
在配置时,可以使用星号
*作为通配符,但是,它只能匹配1级路径,例如:
/user/*可以通配
/user/reg.do、
/user/login.do等,却无法匹配
/user/a/list.do!如果需要表示多级路径中的通配,则需要使用2个星号
**!
过滤器与拦截器的区别
使用环境不同:过滤器是Java EE中的组件,任何Java Web项目都可以使用;拦截器是SpringMVC中的组件,仅当项目中使用了SpringMVC框架后才可以使用!
执行时间节点不同:过滤器是执行在Servlet之前的,拦截器是执行在Controller之前的(暂不考虑拦截器在控制器之后的2次执行)!
使用复杂程度不同:过滤器只能配置1个路径(
<url-pattern>)表示过滤范围,拦截器可以配置若干个
<mvc:mapping>表示拦截范围,同时还可以使用若干个
<mvc:exclude-mapping>表示例外(白名单),所以配置时更加灵活!
当然,也有一些相同之处,例如:都在控制器之前执行,都可以起到“拦截效果”,都可以形成“链”。
- 学习笔记八 过滤器和拦截器
- avalon学习笔记之拦截器与过滤器的区别
- 黑马程序员---struts2学习笔记之六(自定义拦截器)
- Vue学习笔记四:过滤器
- SpringBoot 过滤器,拦截器初步学习整理(有示例代码)
- Struts2 学习笔记11--拦截器
- Spring学习笔记(13)——aop原理及拦截器
- spring学习笔记 -- 拦截器(一)
- Struts2中的拦截器与过滤器学习
- SpringMVC学习笔记2_拦截器实现登录验证
- springboot学习笔记2(拦截器,redis,授权登录,读取yml配置文件)
- 拦截器---SpringMVC学习笔记(十四)
- Springmvc第三讲学习笔记,拦截器Interceptor的使用
- Struts 2 拦截器底层实现原理 学习笔记
- JQUERY1.9学习笔记 之基本过滤器(三)偶数选择器
- Hibernate学习---第十四节:hibernate过滤器和拦截器的实现
- 学习笔记_第一个strut程序_之中文乱码,过滤器解决方案及过程总结
- Vue入门学习笔记【基本概念、对象、过滤器、指令等】
- node.js学习笔记(3)-node.js结合mysql数据库实现的web项目中常见功能--登录验证、session传值、拦截器、ajax传值等
- Hibernate学习---第十三节:hibernate过滤器和拦截器的实现