springMVC 拦截器和filter用法

来源:互联网 发布:onclick=javascript: 编辑:程序博客网 时间:2024/06/05 12:41

1.SpringMVC拦截器工作原理
如果要实现SpringMVC拦截器,就需要实现HandlerInterceptor接口:

public interface HandlerInterceptor {     default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {       //handle:被拦截的请求的目标对象        return true;   //这个返回值:表示我们是否需要将当前的请求拦截下来 false:请求拦截 true请求会被执行 }       default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { }//modelAndView 参数来改变显示的视图或者发往视图的方法modelAndView.setViewName();       default void afterCompletion(HttpServletResquest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { }}
有时我们需要其中的某个方法,并实现其他的方法有些冗余,这时Spring提供适配器
(HandlerInterceptorAdapter)的方法,继承HandlerInterceptorAdapter可以任意实现自己需要的方法。
三个方法执行的顺序:
preHandle(),在Controller执行前执行,比如进行数据校验
postHandle(),在Controller执行完后,但没有进行ModelAndView渲染时,执行。
afterCompletion,在ModelAndView渲染完后执行。
2.添加SpringMVC拦截器
2.1编写拦截器

package com.intercepter;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * Created  on 2017/8/17. */public class  loginCtrl implements HandlerInterceptor {    @Override    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {        System.out.println(getClass().getName()+"  preHandle");        return true;    }    @Override    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {        System.out.println(getClass().getName()+"  postHandle");    }    @Override    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {        System.out.println(getClass().getName()+"  afterCompletion");    }}
2.2编写控制器
@Controllerpublic class LoginCtrl {    //..}

2.3将控制器和拦截器注册成Bean
先按照简单的<bean>标签来注册,后续会介绍利用JavaConfig配置和注解配置
<bean class="xxx.ClassName"/>
2.4在SpringMVC配置文件中配置拦截器
HandlerMapping将请求映射为HandlerExecutionChain对象,而该对象包含一个Handler(处理器)和多个
Handler-Interceptor(拦截器)。可想而知,需要在HandlerMapping中配置HandlerInterceptor,提倡使用
下面这中方式:
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"><mvc:interceptors>            <mvc:interceptor>                   <!--                         /**的意思是所有文件夹及里面的子文件夹                        /*是所有文件夹,不含子文件夹                        /是web项目的根目录                     -->                    <mvc:mapping path="/**" />                    <!-- 需排除拦截的地址 -->                     <!--  <mvc:exclude-mapping path="/userController/login"/>  -->                   <bean id="loginCtrl" class="com.loginCtrl"></bean> <!--这个类就是我们自定义的Interceptor -->          </mvc:interceptor>           <!-- 当设置多个拦截器时,先按顺序调用preHandle方法,然后逆序调用每个拦截器的postHandle和afterCompletion方法  -->    </mvc:interceptors>
3:Filter工作原理
HandlerInterceptor必须基于SpringMVC环境下才能使用,是有局限性的。所以推荐使用符合Servlet规范的Filter,它是最通用,而且是最先使用的。Filter对请求进行预处理,对响应进行后处理。可以依次定义多个Filter,它们会形成FilterChain,按照栈模型的方式,依次执行。了解下Filter的内部结构:
public interface Filter {    void init(FilterConfig filterconfig) throws ServletException;    void doFilter(ServletRequest request, ServletResponse response,                         FilterChain filterChain) throws ServletException, IOException;    void destory();}
从代码中可见,Filter,FilterConfig,FilterChain是实现过滤器的关键。
FilterConfig的内部实现如下:
public interface FilterConfig {  String getFilterName(); //获取FilterName  String getInitParameter(String name); //获取初始化的参数值  Enumeration<String> getInitParameterNames(); //通过枚举获取参数  String getServletContext(); //获取Filter所属的上下文
从代码中可见,Filter,FilterConfig,FilterChain是实现过滤器的关键。
该接口用于init(FilterConfig filterConfig)方法中,获取web.xml中Filter的配置。可以在filter标签中初始化变量,然后通过filterConfig来获取。可以理解成,web.xml中某个Filter是对应的FilterConfig的实例对象
init()方法,由web容器来调用,仅初始化一次,初始化Filter。doFilter()方法,调用filterChain.doFilter(req, res)对请求或响应进行处理。destory()方法,由web容器来调用,仅初始化一次,通常用做释放资源。
4:添加Filter
servlet3.0开始支持注解开发了,这里先介绍用xm配置Filter,这里简单描述添加步骤
4.1编写自己的Filter实现Filter中的接口
public class MyFilter implements Filter {    //init, doFilter, destory实现}
4.2:在web.xml中注册Filter并设置映射路径
filter>    <!--类似于配置Servlet,需要class位置,该class的代号 -->    <filter-name>filterName</filter-name>    <filter-class></filter-class>    <!-- 可初始化参数-->    <init-param>    </init-param>    <!--允许多个初始化多个参数 -->    <init-param>    </init-param></filter><filter-mapping>    <filter-name>filterName</filter-name>    <url-pattern>/*</url-pattern></filter-mapping>