您的位置:首页 > 编程语言 > Java开发

springmvc 拦截器 与 servlet filter比较

2017-03-20 20:48 337 查看
为了讲解filter 和interceptor之间的区别,我会从 作用范围,作用原理,作用效果来说明两者之间的关系。

springMVC拦截器:

作用范围:拦截的目标只是controller ,也就是处理器(handler)。一般要继承 HandlerInterceptorAdapter,其中方法如下:

/* preHandle是一开始就 执行的 方法,并由返回的结果决定--> 后面的 拦截器是否执行 */
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
if(condition){
return true;
}else{
return false;
}
}

/* postHandle 是controller正常执行完成后,执行的方法。如果没有正常执行完成,所有的postHandle 方法都不会执行 */
/* 该方法在controller正常执行完成之后 才会执行,并且在 中央处理器 渲染页面之前 执行。 */
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("postHandle 执行!!!");
}

/* afterCompletion 是只要该拦截器的preHandle 方法执行的结果为true ,该方法就执行 */
/*
* afterCompletion 在所有的工作完成之后,且该该拦截器的 preHandle 返回的结果是 true ,该方法相当于
* try-catch-finally 中的finally ,用来释放一些资源。
*/
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("afterCompletion 执行!!!");
}
并且要在 spring-mvc.xml文件中配置:

<!--配置拦截器, 多个拦截器,顺序执行 ,路径拦截的相同也是互不影响的。-->
<mvc:interceptors>
<mvc:interceptor>
<!-- 匹配的是url路径, 如果不配置 或 /**,将拦截所有的Controller -->
<mvc:mapping path="/**" />
<bean class="interceptor.MyInterceptor"></bean>
</mvc:interceptor>
<!-- 当设置多个拦截器时,先按顺序调用preHandle方法,然后逆序调用每个拦截器的postHandle和afterCompletion方法 -->
</mvc:interceptors>
这里有必要展示一下web.xml 中的 DispatcherServlet的配置:
<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:config/spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>/</url-pattern> <!-- 不可以用 /* 来代替所有的路径 -->
</servlet-mapping>
因为拦截器是在DispatcherServlet的基础上进一步处理的,这是因为只有经过DispatcherServlet处理后的路径并转发到相应的Controller上,这样同时也理解为springmvc框架处理的路径是 DispatcherServlet处理路径的子集。并且拦截器只能包装到controller上,无法直接拦截静态资源,或jsp、servlet等资源。另一方面,只要是满足路径的匹配,就会拦截,没有根据请求方式选择是否拦截的途径。

Filter:

Filter是javax.servlet.Filter ,作为最基本的过滤装置,是web请求拦截中的基本拦截方式,但是其功能强大,并不简单。Filter 是web级别的拦截器或过滤器,这是因为它可以拦截web中所有的资源,或请求路径,并且还可以自主选择拦截的请求方式。特此说明上面讲的确实是 可以拦截web项目中的所有的资源,无论是servlet ,jsp 还是其他动态资源,如 Controller 还可以是 action ,还可以拦截静态资源
,*.html  、*.js、* .jpg ,*css……都可以拦截。

使用的话要实现 javax.servlet.Filter 接口,

public class JspFilter implements Filter {

@Override
public void destroy() {
// TODO Auto-generated method stub

}

@Override
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
//首先将闯过来的值 扩展到大的子类
HttpServletRequest request=(HttpServletRequest)req ;
HttpServletResponse response=(HttpServletResponse)resp;
System.out.println("过滤之前");
chain.doFilter(request, response);
System.out.println("过滤之后");
}

@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 初始化web.xml中的值,方便配值,比如填上排除过滤的相

}

}

在web.xml 中的配置:

<filter>
        <filter-name>myFilter</filter-name>
        <filter-class>filter.JspFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>myFilter</filter-name>
        <url-pattern>/*</url-pattern>
<!-- <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
        <dispatcher>ERROR</dispatcher> -->
    </filter-mapping> 


这里说明Filter的拦截方式:

<dispatcher>REQUEST</dispatcher> (默认的) :直接访问目标资源时,包括在地址栏中直接访问,表单提交,超链接,重定向,只要是在地址栏中可以看到目标资源路径就是 REQUEST 

<dispatcher>FORWARD</dispatcher>  :转发执行过滤器,包括requestDispatcher.forward()方法。以及<jsp:forward >标签都是转发访问。

<dispatcher>INCLUDE</dispatcher>  :包含访问执行过滤器,包括requestDispatcher.include()方法。<jsp:include> 标签都是包含访问。

<dispatcher>ERROR</dispatcher>  当目标资源在web.xml中配置<error-page>中时,并且真的出现了异常,转发到目标资源时,就会执行过滤器。

这些都是非常重要的配置。

相信大家从中可以了解一些新的见解,自己能力毕竟有限,希望大家指出不足之处。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: