spring mvc拦截器的作用:
springmvc拦截器功能和 servlet 的 filter类似,但是他是专门为spring mvc的httprequest路由定制的。
springmvc 的拦截器有3个函数,分别在
①、controller函数被调用之前 (被函数若返回false,则controller函数不会被调用,后面的②③函数也不在被调用,本函数处理完本http请求)
②、controller函数被调用后调用视图之前,
③、调用时图之后执行
因此,springmvc的拦截器特别适用于 【检查用户是否登录,以确定用户是否能够访问某些页面】的功能
使用springmvc拦截器的步骤:
1、添加自定义类,继承 HandlerInterceptorAdapter 类 (本类一般放在 interceptor 包中)
本类中重写上面①、②、③ 3个函数,并在函数中做逻辑判断,下面是函数①的代码示例:
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if(request.getMethod()=="POST")
return true;
else {
HttpSession httpSession = request.getSession(false); //若当前没有session,则不创建session
if (httpSession == null || httpSession.getAttribute("user") == null) //未登录状态
{
RequestDispatcher rd = request.getRequestDispatcher("/jsp/login.jsp");
rd.forward(request, response);
return false;
} else
return true;
}
}
2、spring-mvc的xml文件中添加节点 : 其中可以使用通配符: 【*】-本层目录下所有字符串 【**】本层目录下任意层子目录中的字符串
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" /><!-- /*只能拦截 /login,不能拦截如 /admin/adduser ; /** 可以拦截所有的url -->
<mvc:exclude-mapping path="/admin/**" /> <!--这里也可以使用通配符*和**,其中*代表一层目录,**代表一层或多层目录-->
<mvc:exclude-mapping path="/registbyemail" />
<mvc:exclude-mapping path="/registbyphone" />
<mvc:exclude-mapping path="/useremailactivate" />
<bean class="interceptor.NeedLoginInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
执行工程,发现拦截器已经开始起作用了
代码示例:
package interceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class NeedLoginInterceptor extends HandlerInterceptorAdapter {
// private static final Logger logger = LoggerFactory.getLogger(LogsInterceptor.class);
//
// private NamedThreadLocal<String> logContext = new NamedThreadLocal<String>("log-id");
//
// @Autowired
// private TLogDao logDao;
/**
* preHandle方法是进行处理器拦截用的,顾名思义,该方法将在Controller处理之前进行调用,
* SpringMVC中的Interceptor拦截器是链式的,可以同时存在多个Interceptor,
* 然后SpringMVC会根据声明的前后顺序一个接一个的执行,
* 而且所有的Interceptor中的preHandle方法都会在Controller方法调用之前调用。
* SpringMVC的这种Interceptor链式结构也是可以进行中断的,
* 这种中断方式是令preHandle的返回值为false,当preHandle的返回值为false的时候,controller函数不会被执行,
* 此时需要在本函数中使用 request.getRequestDispatcher("/WEB-INF/view/login.jsp").forward(request, response)
* 来把请求交由 jsp 页面执行
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if(request.getMethod()=="POST")
return true;
else {
HttpSession httpSession = request.getSession(false); //若当前没有session,则不创建session
if (httpSession == null || httpSession.getAttribute("user") == null) //未登录状态
{
RequestDispatcher rd = request.getRequestDispatcher("/jsp/login.jsp");
rd.forward(request, response);
return false;
} else
return true;
}
}
/**
* 这个方法只会在当前这个Interceptor的preHandle方法返回值为true的时候才会执行。
* postHandle是进行处理器拦截用的,它的执行时间是在处理器进行处理之 后, 也就是在Controller的方法调用之后执行,
* 但是它会在DispatcherServlet进行视图的渲染之前执行,也就是说在这个方法中你可以对ModelAndView进行操作。
* 这个方法的链式结构跟正常访问的方向是相反的,也就是说先声明的Interceptor拦截器该方法反而会后调用,
* 这跟Struts2里面的拦截器的执行过程有点像,
* 只是Struts2里面的intercept方法中要手动的调用ActionInvocation的invoke方法,
* Struts2中调用ActionInvocation的invoke方法就是调用下一个Interceptor或者是调用action,
* 然后要在Interceptor之前调用的内容都写在调用invoke之前,要在Interceptor之后调用的内容都写在调用invoke方法之后。
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
/**
* 该方法也是需要当前对应的Interceptor的preHandle方法的返回值为true时才会执行。
* 该方法将在整个请求完成之后,也就是DispatcherServlet渲染了视图执行, 这个方法的主要作用是用于清理资源的,
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
}
}