在开发是可能会遇到:某些网站只能希望几个特定的用户浏览,对于这种访问权限控制需要使用拦截器。
1、拦截器的概述
spring MVC的拦截器与java Servlet的过滤器类似,主要用于拦截用户的请求做出响应的处理
通常在权限验证、记录请求信息的日志、判断用户手否登陆功能上。
1、拦截器的定义
在spring MVC框架中定义一个拦截器需要对拦截器进行定义和配置,定义一个拦截器可以通过两种方式:
①、通过实现HandlerInterceptor接口或者HandlerInterceptor接口来实现定义
②、实现WebRequestInterceptor接口或者继承WebRequestInterceptor接口实现来定义。
实例:
public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { return false; } @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { } }
preHandle:在控制器的处理请求方法前执行,其返回值表示是否中断后续操作,返回true表示继续向下执行,返回为false表示终端后续操作。
postHandle:在控制器的处理请求方法调用之后、解析视图执行之前执行,可以通过此方法对请求域中的模型和视图做进一步的修改。
afterCompletion:在控制器的处理请求完成过后执行,即视图渲染结束后,可以通过此方法来实现一些资源的清理,记录日志信息等工作。
2、拦截器的配置
让自定义的拦截器生效需要在spring mvc的配置文件中进行配置,配置代码如下:
<!--配置拦截器--> <mvc:interceptors> <!--配置一个全局的拦截器,拦截所有请求 --> <bean class="Interceptor.MyInterceptorAll"></bean> <mvc:interceptor> <mvc:mapping path="/**"/> <!--配置不需要拦截的路径--> <mvc:exclude-mapping path="/"></mvc:exclude-mapping> <!--表示匹配路径下的请求才进行拦截--> <bean class="Interceptor.MyInterceptor"></bean> </mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/**"/> <!--配置不需要拦截的路径--> <mvc:exclude-mapping path="/"></mvc:exclude-mapping> <!--表示匹配路径下的请求才进行拦截--> <bean class="Interceptor.MyInterceptor1"></bean> </mvc:interceptor> </mvc:interceptors>
<mvc:interceptors>元素用于配置一组拦截器,子元素<bean>定义的时全局拦截器,即拦截所有的请求。
<mvc:interceptor>元素定义的是指定路径的拦截器,子元素<mvc:mapping>用于配置拦截器作用的路径,
该路径在path属性中定义 /** 代表拦截所有的i请求
<mvc:exclude-mapping path="/">:请求中包含不需要拦截的内容,在path属性中指定。
这里需要注意的是:
这里的每个标签的顺序
2、拦截请求执行的流程
1、单个拦截器的执行流程
直接看代码进行演示:
拦截类:
public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { System.out.println("preHandle...."); return true; } @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { System.out.println("postHandle...."); } @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { System.out.println("afterCompletion....."); } }
controller类:
@Controller public class interceptorController { @RequestMapping("/gototest") public String test(){ System.out.println("test...."); return "test"; } }
配置文件:
<!--配置拦截器--> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/gototest"/> <!--配置不需要拦截的路径--> <mvc:exclude-mapping path="/"></mvc:exclude-mapping> <!--表示匹配路径下的请求才进行拦截--> <bean class="Interceptor.MyInterceptor"></bean> </mvc:interceptor> </mvc:interceptors>
前端页面
<body>
拦截器的测试视图....
</body>
访问请求之后:
查看后台的打印顺序:
2、多个拦截器的执行流程
在单个拦截器的基础上新建一个拦截器:
public class MyInterceptor1 implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { System.out.println("preHandle11...."); return true; } @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { System.out.println("postHandle11...."); } @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { System.out.println("afterCompletion11....."); } }
配置文件:
<!--配置拦截器--> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/gototest"/> <!--配置不需要拦截的路径--> <mvc:exclude-mapping path="/"></mvc:exclude-mapping> <!--表示匹配路径下的请求才进行拦截--> <bean class="Interceptor.MyInterceptor"></bean> </mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/gototest"/> <!--配置不需要拦截的路径--> <mvc:exclude-mapping path="/"></mvc:exclude-mapping> <!--表示匹配路径下的请求才进行拦截--> <bean class="Interceptor.MyInterceptor1"></bean> </mvc:interceptor> </mvc:interceptors>
测试:
后台的顺序:
3、用户登陆的权限验证
controller类:
@Controller public class LoginController { //登陆页面初始化 @RequestMapping("/toLogin") public String logiin(){ return "tologin"; } //处理登陆功能 @RequestMapping("/login") public String login(Users users, Model model, HttpSession session){ System.out.println(users); if (users.getName().equals("admin") && users.getPwd().equals("123")){ //登陆成功 session.setAttribute("user",users); return "loginsuccess"; }else { model.addAttribute("msg","账号或者密码错误!!!"); return "tologin"; } } }
拦截器的配置:
public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { System.out.println("preHandle11...."); Object object = httpServletRequest.getSession().getAttribute("user"); if (object == null){ httpServletRequest.getRequestDispatcher(httpServletRequest.getContextPath()+ "/toLogin"). forward(httpServletRequest,httpServletResponse); httpServletRequest.setAttribute("msg","没有权限进行登陆!!!"); return false; }else { return true; } } @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { System.out.println("postHandle11...."); } @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { System.out.println("afterCompletion11....."); } }
配置文件:
<!--配置拦截器--> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <!--配置不需要拦截的路径--> <mvc:exclude-mapping path="/toLogin"></mvc:exclude-mapping> <mvc:exclude-mapping path="/login"></mvc:exclude-mapping> <!--表示匹配路径下的请求才进行拦截--> <bean class="Interceptor.LoginInterceptor"></bean> </mvc:interceptor> </mvc:interceptors>
前端页面:
tologin.jsp
<body> ${msg} <br> <form action="<%=request.getContextPath()%>/login" method="post"> name:<input type="text" name="name" ><br> pwd:<input type="text" name="pwd" ><br> <input type="submit" value="submit"> </form> </body>
loginsuccess.jsp
<body>
welcome:${user.name}
</body>
测试数据:
结果: