SpringMVC-拦截器做一个登录认证的小Demo
拦截器
拦截器的定义
处理器拦截器类似于servlet开发中的filter,用于对处理器进行预处理和后处理。
定义拦截器,实现handlerinterceptor这个接口
接口的实现需要导入包import org.springframework.web.servlet.handlerinterceptor;
这个包不能导错,不然不能自动添加方法。
代码:
package com.jch.interceptor; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; import org.springframework.web.servlet.handlerinterceptor; import org.springframework.web.servlet.modelandview; public class handlerinterceptor1 implements handlerinterceptor{ /** * 进入handler方法之前执行 * 用于身份认证,身份校验 * 比如身份认证,如果认证不通过表示当前用户没有登录,需要此方法拦截不在向下执行 */ @override public boolean prehandle(httpservletrequest arg0, httpservletresponse arg1, object arg2) throws exception { // todo auto-generated method stub return false; } /** * 进入handler之后,返回modelandview之前执行 * 应用场景从modelandview出发,将共用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一制定视图 */ @override public void posthandle(httpservletrequest arg0, httpservletresponse arg1, object arg2, modelandview arg3) throws exception { // todo auto-generated method stub } /** * 执行handler完成执行此方法 * 应用场景:统一异常处理,统一日志处理 */ @override public void aftercompletion(httpservletrequest arg0, httpservletresponse arg1, object arg2, exception arg3) throws exception { // todo auto-generated method stub } }
拦截器的配置
springmvc拦截器针对handlermapping进行拦截设置
springmvc拦截器针对handlermapping进行拦截器设置
如果在某个handlermapping中配置拦截,经过该handlermapping映射成功的handler最终使用该拦截器。
一般不推荐使用,配置过于麻烦
类似全局的拦截器
springmvc配置类似全局的拦截器,springmvc框架将配置的类似全局的拦截器注入到每一个handlermapping中
拦截器的测试
测试需求
测试多个拦截器各个方法的执行时机
编写两个拦截器
代码;
package com.jch.interceptor; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; import org.springframework.web.servlet.handlerinterceptor; import org.springframework.web.servlet.modelandview; public class handlerinterceptor1 implements handlerinterceptor{ /** * 进入handler方法之前执行 * 用于身份认证,身份校验 * 比如身份认证,如果认证不通过表示当前用户没有登录,需要此方法拦截不在向下执行 */ @override public boolean prehandle(httpservletrequest request, httpservletresponse response, object handler) throws exception { // todo auto-generated method stub system.out.println("这是第1个拦截器,prehandle方法"); return false; } /** * 进入handler之后,返回modelandview之前执行 * 应用场景从modelandview出发,将共用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一制定视图 */ @override public void posthandle(httpservletrequest arg0, httpservletresponse arg1, object arg2, modelandview arg3) throws exception { // todo auto-generated method stub system.out.println("这是第1个拦截器,posthandle方法"); } /** * 执行handler完成执行此方法 * 应用场景:统一异常处理,统一日志处理 */ @override public void aftercompletion(httpservletrequest arg0, httpservletresponse arg1, object arg2, exception arg3) throws exception { // todo auto-generated method stub system.out.println("这是第1个拦截器, aftercompletion方法"); } }
两个拦截器都放行
将两个return都改为true
在浏览器中随意访问一个路由看效果:
这是第1个拦截器,prehandle方法
这是第2个拦截器,prehandle方法
这是第2个拦截器,posthandle方法
这是第1个拦截器,posthandle方法
这是第2个拦截器,aftercompletion方法
这是第1个拦截器, aftercompletion方法
总结:
prehandle方法按顺序执行
posthandle方法和aftercompletion方法按拦截器配置的逆向顺序执行
拦截器1放行,拦截器2不放行
结果:
这是第1个拦截器,prehandle方法
这是第2个拦截器,prehandle方法
这是第1个拦截器, aftercompletion方法
总结:
拦截器1放行,拦截器的prehandle方法才会执行
拦截器2的prehandle方法不放行,拦截器2的posthandle方法和aftercompletion方法不会执行。
只要有一个拦截器拦截不放行posthandle方法都不会执行
拦截器1不放行,拦截器2不放行
结果:
这是第1个拦截器,prehandle方法
总结:
拦截器1 prehandle方法不放行,posthandle方法和aftercompletion方法都不会执行
拦截器1 prehandle方法不放行,拦截器2不执行。
小结
根据测试结果,对拦截器应用。
比如:
统一日志处理拦截器,需要该拦截器prehandler一定要放行,且将它放在拦截器链接中的第一个位置。
登录认证的拦截器,放在拦截器链接中的第一个位置
权限校验拦截器,放在登录校验拦截器之后。(因为登录通过后才校验权限)
拦截器的应用(实现登录认证)
需求
1、 用户请求url
2、 拦截器进行校验
如果请求的url是公开地址(无需登录就能访问的url),让放行。、
如果用户session不存在跳转到登录界面
如果用户session存在,继续操作
登录的controller方法
package com.jch.controller; import javax.servlet.http.httpsession; import org.springframework.stereotype.controller; import org.springframework.web.bind.annotation.requestmapping; @controller public class logincontroller { // 登录 @requestmapping("login.jch") public string login(httpsession session , string username , string password) { // 调用service进行用户身份验证 // ...这里假设验证通过 // 在session中保存用户身份信息 session.setattribute("username", username); return "redirect:/register.jch"; // /为项目根目录 } // 退出登录 @requestmapping("logout.jch") public string login(httpsession session) { // 清楚session数据 session.invalidate(); return "redirect:/login.jch"; } }
登录认证拦截的实现
代码实现
package com.jch.interceptor; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; import javax.servlet.http.httpsession; import org.springframework.web.servlet.handlerinterceptor; import org.springframework.web.servlet.modelandview; public class logininterceptor implements handlerinterceptor{ /** * 进入handler方法之前执行 * 用于身份认证,身份校验 * 比如身份认证,如果认证不通过表示当前用户没有登录,需要此方法拦截不在向下执行 */ @override public boolean prehandle(httpservletrequest request, httpservletresponse response, object handler) throws exception { // todo auto-generated method stub // 获取请求的url string url = request.getrequesturi(); // 判断是否是公开地址(实际使用将公开地址配置在配置文件中)这里公开地址就是登录提交的地址 if(url.indexof("login.jch")>=0) { // 如果要登录提交,那么放行 return true; } // 判断session httpsession session = request.getsession(); string username = (string)session.getattribute("username"); if(username != null) { // 有身份信息,放行 return true; } // 身份验证不通过跳转到登录界面 request.getrequestdispatcher("/views/home/login.jsp").forward(request, response); system.out.println("这是第1个拦截器,prehandle方法"); return false; } /** * 进入handler之后,返回modelandview之前执行 * 应用场景从modelandview出发,将共用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一制定视图 */ @override public void posthandle(httpservletrequest arg0, httpservletresponse arg1, object arg2, modelandview arg3) throws exception { // todo auto-generated method stub system.out.println("这是第1个拦截器,posthandle方法"); } /** * 执行handler完成执行此方法 * 应用场景:统一异常处理,统一日志处理 */ @override public void aftercompletion(httpservletrequest arg0, httpservletresponse arg1, object arg2, exception arg3) throws exception { // todo auto-generated method stub system.out.println("这是第1个拦截器, aftercompletion方法"); } }
配置拦截器
在springmvc的前端控制器配置文件中配置interceptor拦截器
<!-- 配置拦截器 --> <mvc:interceptors> <!-- 多个拦截器,顺序执行 --> <!-- 登录认证拦截器 --> <mvc:interceptor> <mvc:mapping path="/**"/><!-- 标识拦截所有的url包括所有的子url --> <bean class="com.jch.interceptor.logininterceptor"></bean> </mvc:interceptor> </mvc:interceptors>
启动tomcat查看测试结果。
下一篇: 稀疏数组