1.实现了HandleInterceptor
public class LoginInterceptor implements HandlerInterceptor {
@Override
// 在Handler(controller)方法执行之前执行
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// false 表示拦截
// true 表示放行
// 直接从Session中查询用户数据
User cache = null;
cache = (User) request.getSession().getAttribute("user");
// user has not login
if (cache == null) {
// forward to login page
//request.getRequestDispatcher("/index.jsp").forward(request, response);
//redirect to the login page
response.setCharacterEncoding("utf-8");
response.sendRedirect("http://localhost:8090/SSMXML/");
return false;
}
// user has login
return true;
}
@Override
// 在Handler(Controller)方法执行后,返回ModelAndView之前执行
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
@Override
// 在Handler(controller)方法执行后执行
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
}
2.三个关注点( 重复的代码形成的方法就是关注点。(只需要写一次))详解,具体思想参考Spring切面编程
@Override
//在Handler(controller)方法执行之前执行
//使用场景: 权限认证,身份认证
//return false:表示拦截,不向下执行
//return true:放行
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {
return false;
}
@Override
//在Handler(Controller)方法执行后,返回ModelAndView之前执行
//使用场景: 菜单导航,存放公用的模型或试图
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {
}
@Override
//在Handler(controller)方法执行后执行
//使用场景: 由于这里我们获取了异常对象,所以可以用于统一的异常处理 还可以用于统一的日志处理
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {
}
3.拦截器的配置
1.和struts拦截器链不同的是,SpringMVC拦截器是作用在HandlerMapping的。
如果存在某一个HandlerMapping中配置了拦截器,进过该HandlerMapping映射成功的Handler(Controller)才能够被拦截器拦截
补充: SpringMVC中可以配置多个处理器映射器(HandlerMapping)
问题: 如何配置一个全局的拦截器,让其作用于所有的处理器映射器(HandlerMapping)
2.配置单一处理器映射器(HandlerMapping)的拦截器(一般不推荐使用)
<!-- 注解的 处理器映射器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
<property name="interceptors">
<list>
<ref bean="customInterceptor"/>
</list>
</property>
</bean>
<!--配置拦截器 -->
<bean id="customInterceptor" class="com.ncs.interceptor.CustomInterceptor"></bean>
3.配置全局拦截器,作用于所有的处理器映射器(HandlerMapping)实际使用
<!--全局拦截器配置 -->
<mvc:interceptors>
<!--可以配置多个拦截器 -->
<mvc:interceptor>
<!--指定拦截哪些请求url,/**表示拦截根路径url和其上一级url,/*表示拦截根url(依此类推) -->
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/login"/>
<!--指定拦截器实现类 -->
<bean class="com.ncs.interceptor.LoginInterceptor"></bean>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.ncs.interceptor.CustomInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
4.多个拦截器一起使用的执行顺序问题
1.拦截器1放行,拦截器2放行
拦截器1 preHandle
拦截器2 preHandle
拦截器2 postHandle
拦截器1 postHandle
拦截器2 afterCompletion
拦截器1 afterCompletion
2.拦截器1放行,拦截器2不放行
拦截器1 preHandle
拦截器2 preHandle
拦截器1 afterCompletion
3.拦截器1不放行,拦截器2放行
拦截器1 preHandle
4.拦截器1不放行,拦截器2不放行
拦截器1 preHandle
实际使用案例:1.同一日志拦截器: 2.登录认证拦截器:3.权限校验拦截器:
5.实现登录认证:
1.用户请求url
2.拦截器进行拦截校验
1.如果请求的URl是公开地址(无需登录即可访问的url) 放行
2.如果请求的url是拦截地址
1.如果用户session存在,放行,继续操作
2.如果用户session不存在,跳转到登录页面