public interface HandlerInterceptor { boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception; void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception; void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception;}preHandle:预处理回调方法,实现处理器的预处理(如登录检查),第三个参数为响应的处理器(如我们上一章的Controller实现);返回值:true表示继续流程(如调用下一个拦截器或处理器); false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应;
postHandle:后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null;
afterCompletion:整个请求处理完毕回调方法,即在视图渲染完毕时回调;
如果我们不想实现全部的方法,只使用其中的部分方法,可以继续HandlerInterceptorAdapter(适配器模式)
public class MyInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // TODO Auto-generated method stub return super.preHandle(request, response, handler); } }入门小程序
定义拦截器:
public class MyInterceptorOne implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("MyInterceptorOne===preHandle"); return true; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("MyInterceptorOne===postHandle"); } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("MyInterceptorOne===afterCompletion"); }}MyInterceptorTwo同MyInterceptorOne,但是sysout需要修改;配置文件:
<!-- 映射器 --> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"> <property name="interceptors"> <list> <ref bean="myInterceptorOne"/> <ref bean="myInterceptorTwo"/> </list> </property> </bean> <!-- 适配器 --> <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/> <!-- 试图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> <!-- 处理器 --> <bean name="/hello" class="springMVC.HelloWorldController"></bean> <!-- 拦截器 --> <bean id="myInterceptorOne" class="lee.springmvc.interceptor.MyInterceptorOne"></bean> <bean id="myInterceptorTwo" class="lee.springmvc.interceptor.MyInterceptorTwo"></bean> 访问hello控制台输出如下:MyInterceptorOne===preHandleMyInterceptorTwo===preHandleMyInterceptorTwo===postHandleMyInterceptorOne===postHandleMyInterceptorTwo===afterCompletionMyInterceptorOne===afterCompletion用拦截器我们可以进行拦截登录:public class LoginInterceptor extends HandlerInterceptorAdapter{ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //1、请求到登录页面 放行 if(request.getServletPath().startsWith("loginUrl")) { return true; } //2、比如退出、首页等页面无需登录 //3、如果用户已经登录 放行 if(request.getsession().getAttribute("username") != null) { //更好的实现方式的使用cookie return true; } //4、如果页面上某个按钮进行Ajax请求后台数据。用户请求前,服务器突然关掉,之后服务器启动,用户正好点击按钮进行ajax后台请求 //此时应该进行重定向到登录页面,需要加上如下代码,否则页面不发送任何改变 if("xmlHttpRequest".equals(request.getHeader("X-Requested-With")) && request.getSession().getAttribute("username") == null){//判断是否为ajax请求 PrintWriter out = response.getWriter();//如果是ajax请求,返回一个标识,告诉ajax请求无效,需要重新登录 out.print("login"); return false; } //5、非法请求 即这些请求需要登录后才能访问 //重定向到登录页面 response.sendRedirect(request.getContextPath() + "loginUrl"); return false; } }推荐能使用servlet规范中的过滤器Filte
新闻热点
疑难解答