SpringMVC必知必会的过滤器与拦截器
1:什么是过滤器(Filter)过滤器Filter:过滤器通过实现Filter接口,实现了过滤器的三个方法,分别是初始化方法,dofilter方法和销毁方法,随着容器的启动和销毁而初始化和销毁,依赖于servlet容器,过滤器拦截的是地址栏请求,过滤器实在进入容器后执行的servlet之前...
1:什么是过滤器(Filter)
过滤器Filter:过滤器通过实现Filter接口,实现了过滤器的三个方法,分别是初始化方法,dofilter方法和销毁方法,随着容器的启动和销毁而初始化和销毁,依赖于servlet容器,过滤器拦截的是地址栏请求,过滤器实在进入容器后执行的servlet之前后执行,针对的在处理业务之前的操作。
chain.doFilter(request, response);这个方法的调用作为分水岭。事实上调用Servlet的doService()方法是在这个方法中进行的。
1.1代码实现
过滤器代码:
-
public
class Filter1 implements Filter {
-
-
public void destroy() {
-
// TODO Auto-generated method stub
-
System.out.println(
"过滤器1销毁方法");
-
}
-
-
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
-
throws IOException, ServletException {
-
// TODO Auto-generated method stub
-
System.out.println(
"过滤器1,客户端向Servlet发送的请求被我拦截到了");
-
chain.doFilter(request, response);
-
System.out.println(
"过滤器1,Servlet向客户端发送的响应被我拦截到了");
-
}
-
-
public void init(FilterConfig filterConfig) throws ServletException {
-
// TODO Auto-generated method stub
-
System.out.println(
"过滤器1初始化方法");
-
}
-
-
}
xml配置:
-
<filter>
-
<filter-name>filterDemo1
</filter-name>
-
<filter-class>com.thit.filters.Filter1
</filter-class>
-
</filter>
-
<filter-mapping>
-
<filter-name>filterDemo1
</filter-name>
-
<url-pattern>/*
</url-pattern>
-
<!-- /*是对所有的文件进行拦截 -->
-
</filter-mapping>
2:什么是拦截器
拦截器是基于Javaf反射实现的,不依赖于servlet容器,过滤器针对于contraller方法,并且能获取到所有的类,对类里面所有的方法实现拦截,粒度更小,拦截器中可以注入service,也可以调用业务逻辑
2.1代码实现
拦截器1:
-
//拦截器1
-
public
class LoginInterceptor implements HandlerInterceptor{
-
-
-
//预处理1.程序先执行preHandle()方法,如果该方法的返回值为true,则程序会继续向下执行处理器中的方法,否则将不再向下执行。
-
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
-
throws Exception {
-
// TODO Auto-generated method stub
-
System.out.println(
"1:拦截器1,程序进入preHandle方法");
-
User u=(User) request.getSession().getAttribute(
"user");
-
if(u==
null) {
-
System.out.println(
"在进入方法之前判断session的用户是否为空!");
-
System.out.println(
"地址:"+request.getContextPath());
-
//http://localhost:8080/login
-
response.sendRedirect(request.getContextPath()+
"/login");
-
return
false;
-
}
-
-
return
true;
-
}
-
//后处理 2.在业务处理器(即控制器Controller类)处理完请求后,会执行postHandle()方法,然后会通过DispatcherServlet向客户端返回响应。
-
-
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
-
ModelAndView modelAndView)
throws Exception {
-
// TODO Auto-generated method stub
-
System.out.println(
"2:拦截器1,程序进入postHandle方法");
-
-
}
-
//完工之后 3.在DispatcherServlet处理完请求后,才会执行afterCompletion()方法。
-
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
-
throws Exception {
-
// TODO Auto-generated method stub
-
System.out.println(
"3:拦截器1,程序进入afterCompletion方法");
-
-
}
-
-
}
拦截器2:
-
//拦截器2
-
public
class Interceptor2 implements HandlerInterceptor{
-
-
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
-
throws Exception {
-
// TODO Auto-generated method stub
-
System.out.println(
"1:拦截器2,进入到preHandle");
-
return
true;
-
}
-
-
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
-
ModelAndView modelAndView)
throws Exception {
-
// TODO Auto-generated method stub
-
System.out.println(
"2:拦截器2,进入到postHandle");
-
}
-
-
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
-
throws Exception {
-
// TODO Auto-generated method stub
-
System.out.println(
"3:拦截器2,进入到afterCompletion");
-
}
-
-
}
springxml配置:
-
<!--拦截器注册 -->
-
<mvc:interceptors>
-
<!--拦截器1 -->
-
<mvc:interceptor>
-
<!--拦截不同的controller方法 -->
-
<!-- <mvc:mapping path="/users/search"/>
-
<mvc:mapping path="/users/updatepwd"/>
-
<mvc:mapping path="/users/search"/> -->
-
-
-
<!--通配符 拦截子节点和孙节点 -->
-
<mvc:mapping path="/users/**"/>
-
<!--在使用通配符的过程中 排除指定拦截 -->
-
<mvc:exclude-mapping path="/users/search"/>
-
<bean class="com.thit.interceptor.LoginInterceptor">
</bean>
-
</mvc:interceptor>
-
-
<!--拦截器2 -->
-
<mvc:interceptor>
-
<!--拦截不同的controller方法 -->
-
<!-- <mvc:mapping path="/users/search"/>
-
<mvc:mapping path="/users/updatepwd"/>
-
<mvc:mapping path="/users/search"/> -->
-
-
<!--通配符配置 -->
-
<mvc:mapping path="/users/**"/>
-
-
<bean class="com.thit.interceptor.Interceptor2">
</bean>
-
</mvc:interceptor>
-
</mvc:interceptors>
xml配置:
-
<!-- 方法一:这种方式默认读取WEB-INF下的(servlet-name)+(-servlet.xml) springmvc-servlet.xml并且名字是固定的 -->
-
<!-- <servlet>
-
<servlet-name>springmvc</servlet-name>
-
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
-
</servlet>
-
-
<servlet-mapping>
-
<servlet-name>springmvc</servlet-name>
-
<url-pattern>/</url-pattern>
-
</servlet-mapping> -->
-
-
<!-- 方法二:初始化参数命名空间 namespace 必须配置文件在放入在web-inf目录下 -->
-
<!-- <servlet>
-
<servlet-name>springmvc</servlet-name>
-
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
-
<init-param>
-
<param-name>namespace</param-name>
-
<param-value>springmvc-servlet2</param-value>
-
</init-param>
-
</servlet>
-
-
<servlet-mapping>
-
<servlet-name>springmvc</servlet-name>
-
<url-pattern>/</url-pattern>
-
</servlet-mapping> -->
-
-
-
<!-- 方法三:初始化contextConfigLocation,将配置文件放到任意目录下 -->
-
<servlet>
-
<servlet-name>springmvc
</servlet-name>
-
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>
-
<init-param>
-
<param-name>contextConfigLocation
</param-name>
-
<!-- <param-value>WEB-INF/classes/springmvc/springmvc.xml</param-value> -->
-
<param-value>classpath*:springmvc/springmvc.xml
</param-value>
-
</init-param>
-
</servlet>
-
-
<servlet-mapping>
-
<servlet-name>springmvc
</servlet-name>
-
<url-pattern>/
</url-pattern>
-
</servlet-mapping>
3:拦截器于过滤器对比
两者都是AOP编程思想的实现,都能够实现权限控制和日志记录等问题的处理,但是两者粒度不同拦截对象不一样
适用范围不同:Filter是servlet的规范,只能用于web程序,但是拦截器可以用于application等程序。
规范不同:Filter是servlet的规范。但是Interceptor是spring容器支撑,有spring框架支持。
使用资源不一样:spring的拦截器由于依赖spring,也是spring的一个组件,因此能够在拦截器中使用spring的任何资源和对象。例如service对象,数据源,事务管理等,通过ioc注入拦截器即可,而filter不能
粒度不同:Filter只能在servlet的前后起作用,而拦截器能在方法前后异常前后执行,更加灵活,粒度更小,spring框架程序优先使用拦截器。
4:案例执行图
执行结果如下:
/*
0:过滤器1的初始化方法
1:过滤器1,客户端向Servlet发送的请求被我拦截到了
2:拦截器1的前置方法 preHandle
3:拦截器2的前置方法 preHandle
4: controller主方法
5:拦截器2的后置方法postHandle(在controller主方法执行之后执行)
6:拦截器1的后置方法postHandle(在controller主方法执行之后执行)
7:拦截器2的完成后方法afterCompletion(在DispatcherServlet处理完请求后,才会执行)
8:拦截器1的完成后方法afterCompletion(在DispatcherServlet处理完请求后,才会执行)
9:过滤器1,Servlet向客户端发送的响应被我拦截到了
10:过滤器的销毁方法
*/
更多推荐
所有评论(0)