- Servlet为Spring自带的,位于
javax.servlet
包中 - Java_web时,Filter作用是保护服务器资源,如果请求地址符合拦截范围,会先在Servlet之前执行过滤器
- 但在使用了SpringMVC后,Servlet只有一个(
DispatcherServlet
)。使用Filter,会拦截所有请求
- SpringMVC中的拦截器(Interceptor)类似于Servlet中的过滤器(Filter),用于拦截用户请求
- 拦截器定义
- 通过实现
HandlerInterceptor
接口,或继承HandlerInterceptor
接口的实现类(eg:HandlerInterceptorAdapter) - 通过实现
WebRequestInterceptor
接口,或继承WebRequestInterceptor
接口的实现类
- 拦截器、过滤器区别
- 拦截器属于SpringMVC,过滤器属于Servlet
- 拦截器不依赖Servlet容器,由Spring容器初始化;过滤器依赖Servlet容器,由Servlet容器初始化
- 拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用
- 拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问
- 在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次
- 拦截器可以获取IOC容器中的各个bean,而过滤器就不太方便。在拦截器里注入一个Service,可以调用业务逻辑
package com.listao.mvc.interceptor;
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("MyInterceptor.preHandle()");
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
User user = (User) request.getSession().getAttribute("user");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("MyInterceptor.postHandle()");
Map<String, Object> map = modelAndView.getModel();
String msg = (String) map.get("msg");
if (msg != null) {
String newMsg = msg.replaceAll("脏话", "**");
map.put("msg", newMsg);
}
modelAndView.setViewName("/index.jsp");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("MyInterceptor.afterCompletion()");
}
}
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/login"/>
<bean id="myInterceptor" class="com.listao.mvc.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>success.jsp</title>
</head>
<body>
登录成功
<%
System.out.println("success.jsp ==>> 定位MyInterceptor.afterCompletion()");
%>
${requestScope.msg}
</body>
</html>
- 由配置顺序决定。先配置谁,谁就先执行
- 可以理解为拦截器栈,先进后出
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/login"/>
<bean id="myInterceptor" class="com.listao.ssm.interceptor.MyInterceptor"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/login"/>
<bean id="myInterceptor2" class="com.listao.ssm.interceptor.MyInterceptor2"/>
</mvc:interceptor>
</mvc:interceptors>
public class MyInterceptor2 implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("MyInterceptor2.preHandle()");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("MyInterceptor2.postHandle()");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("MyInterceptor2.afterCompletion()");
}
}
MyInterceptor.preHandle()
MyInterceptor2.preHandle()
login() ===>>>
MyInterceptor2.postHandle()
MyInterceptor.postHandle()
success.jsp ==>> 定位MyInterceptor.afterCompletion()
MyInterceptor2.afterCompletion()
MyInterceptor.afterCompletion()