springMVC拦截器和过滤器的简单运用
spring拦截器的定义
什么是拦截器:拦截器顾名思义就是拦截嘛,拦截器可以在我们请求的方法前和方法后加入一些操作,其实也是一种aop的实现策略。
spring要求处理器的拦截器都是实现HandlerInterceptor接口,这个接口定义了三个方法。spring的源码如下:
package org.springframework.web.servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.method.HandlerMethod;
public interface HandlerInterceptor {
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception;
void postHandle(
HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception;
void afterCompletion(
HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception;
}
这个3个方法意义
- preHandle方法:在处理器之前执行的前置方法,该方法的返回值是布尔值Boolean 类型的,当它返回为false 时,表示请求结束,后续的postHandle和afterCompletion都不会再执行;当返回值为true 时就会继续调用下一个postHandle的afterCompletion方法。
- postHandle方法:在处理器之后执行的后置方法,处理器的逻辑完成后运行它
- afterCompletion方法:完成请求处理后执行。主要作用是用于进行资源清理工作。
拦截器的执行流程
拦截器的配置
继承HandlerInterceptorAdapter 类,实现父类的preHandle、postHandle、afterCompletion方法,然后在spring配置文件中配置拦截器,这样就搭建出来了一个简单的拦截器。
package com.hanlin.interceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 拦截器
* @author:hanlin.yuan
* @date:2019/4/23
*/
public class TestInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion");
}
}
spring配置文件
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.hanlin.interceptor.TestInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
servlet过滤器
在Servlet中,如果要定义一个过滤器,则直接让一个类实现javax.servlet.Filter接口即可,此接口定义了三个操作方法:
- init :项目初始化是调用
- doFilter :这个方法才是过滤器最关键的方法,这里可以滤请求的request和返回的response
- destroy :项目关闭的时候调用
package com.hanlin.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* 过滤器
* @author:hanlin.yuan
* @date:2019/04/28
*/
public class TestFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("************************init********************");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
StringBuffer url = request.getRequestURL();
System.out.println(url);
System.out.println("************************doFilter********************");
// 放开请求
chain.doFilter(servletRequest, servletResponse);
return;
}
@Override
public void destroy() {
System.out.println("************************destroy********************");
}
}
然后我在web.xml中启动这个过滤器
<!--过滤器-->
<filter>
<filter-name>testFilter</filter-name>
<filter-class>com.hanlin.filter.TestFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>testFilter</filter-name>
<url-pattern>*</url-pattern>
</filter-mapping>
spring拦截器和servlet过滤器的不同:
- servlet的过滤器是比拦截器先执行的
- 二者适用范围不同。Filter是Servlet规范规定的,只能用于Web程序中,而拦截器既可以用于Web程序,也可以用于Application、Swing程序中
- 规范不同。Filter是在Servlet规范定义的,是Servlet容器支持的,而拦截器是在Spring容器内的,是Spring框架支持的
- 使用的资源不同。同其他代码块一样,拦截器也是一个Spring的组件,归Spring管理,配置在Spring文件中,因此能使用Spring里的任何资源、对象(各种bean),而Filter不行
- 深度不同。Filter只在Servlet前后起作用,而拦截器能够深入到方法前后、异常跑出前后等,拦截器的使用有更大的弹性