玩转Spring!从拒绝Filter开始
来源:互联网 发布:怎么删除网络诽谤信息 编辑:程序博客网 时间:2024/06/03 18:38
一直以来,博客都是在写一些读书笔记或者学习心得。俗话说,举一反三,是时候沉淀一下了。索性这把这篇文章作为开端吧!
笔者知道,这篇文章的题目一定让某些developer不爽,尤其是学习过J2EE基础的人。学习过J2EE基础的童鞋,一定有自己写listener,filter和servlet的经验。经验多一些是好事,但不要陶醉于自己的经验,作为developer,我们还是要进步滴,尤其是在使用Spring之后。
在Spring中,用拦截器代替了原来的listener和filter,而且的确,Spring中的这个拦截器机制也的确是不负众望。下面笔者就举个例子,如何利用Spring中的拦截器机制写出松耦合,可插拔的代码。
多说一句,笔者非常喜欢软件模块“可插拔”的设计。
在大多数的软件架构中,都会有类似登录检查的机制。这个时候,我们就可以写一个拦截器,比如叫LoginInterceptor,让这个类集成自Spring框架的HandlerInterceptor类。
代码如下:
关于HandlerInterceptor的用法,参见SpringMVC官网地址:点击打开链接
public class LoginInterceptor extends HandlerInterceptorAdapter { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if 验证不通过 return false; return true; }}
<bean id="loginInterceptor" class="LoginInterceptor"/><mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <ref bean="loginInterceptor"/> </mvc:interceptor></mvc:interceptors>
瞧,一个身份验证功能写好了。而且,该功能处于系统的最前端,像一层盔甲保护你的系统,无法登陆的用户压根到不了你的web层。那么问题来了,有一天,你的老板和你说:系统要完全公开,希望任何人可以访问;或者是验证登录的逻辑变了,怎么办呢?
当然不仅仅有这些场景,我想说的是这段代码不够松耦合,可插拔度太低。此时怎么办?
别忘了Spring的动态注入机制,现在的代码变成了下面的样子:
public class LoginInterceptor extends HandlerInterceptorAdapter {private InterceptorOne interceptorOne; public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if(!interceptorOne.check(request,response)) return false; return true; } setter方法 }public class InterceptorOne{public boolean check(HttpServletRequest request, HttpServletResponse response){if(检验失败)return false;return true;}}
<bean id="loginInterceptor" class="LoginInterceptor" p:interceptorOne-ref="interceptorOne"/> <bean id="interceptorOne" class="InterceptorOne"/> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <ref bean="loginInterceptor"/> </mvc:interceptor> </mvc:interceptors>
看出区别了吗?在第二种方式中,完全可以通过更改配置文件更换用于验证登录的类,比如有一个新的类MyInterceptor用于登录验证,直接配置xml文件如下即可:
<bean id="loginInterceptor" class="LoginInterceptor" p:interceptorOne-ref="myInterceptor"/><bean id="myInterceptor" class="MyInterceptor"/><mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <ref bean="loginInterceptor"/> </mvc:interceptor></mvc:interceptors>
上面的过程,你仅仅需要改一改xml文件,就可以动态的切换用于验证登录的类了,这就是笔者推崇的可插拔式设计。
先别急着高兴,现在问题又来了! 你的老大不但要求你做登录验证,还要求有黑名单验证,怎么办?上面的设计只能有一个拦截器,办法如下:
public class LoginInterceptor extends HandlerInterceptorAdapter {private List<AbstractInterceptor> interceptorList; public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { while(AbstractInterceptor abstractInterceptor:interceptorList){ if(!abstractInterceptor.check(request, response)) return false; } return true; } setter方法 }public interface AbstractInterceptor{boolean check(HttpServletRequest request, HttpServletResponse response);}public class InterceptorOne implements AbstractInterceptor{boolean check(HttpServletRequest request, HttpServletResponse response){if(登录不通过)return false;return true;}}public class InterceptorTwo implements AbstractInterceptor{boolean check(HttpServletRequest request, HttpServletResponse response){if(在黑名单中)return false;return true;}}
<bean id="loginInterceptor" class="LoginInterceptor" p:interceptorList-ref="interceptors"/><bean id="interceptorOne" class="InterceptorOne"/><bean id="interceptorTwo" class="InterceptorTwo"/><util:list class="ArrayList" id="interceptors"><ref bean="interceptorOne" /><ref bean="interceptorTwo" /></util><mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <ref bean="loginInterceptor"/> </mvc:interceptor></mvc:interceptors>
现在终于放心了,因为你再也不担心加需求了。因为你已经做到业务与框架的解耦了。不但如此,Spring的拦截器,允许自定义需要拦截的URI。
比如在上面黑名单的需求中,你希望/xxxx/**下的URI使用登录验证,/oooo/**下的URI使用黑名单验证,那么他的xml文件如下:
<bean id="xxxxInterceptor" class="LoginInterceptor" p:interceptorList-ref="xxxxInterceptors"/><bean id="ooooInterceptor" class="LoginInterceptor" p:interceptorList-ref="ooooInterceptors"/><bean id="interceptorOne" class="InterceptorOne"/><bean id="interceptorTwo" class="InterceptorTwo"/><util:list class="ArrayList" id="xxxxInterceptors"><ref bean="interceptorOne" /></util><util:list class="ArrayList" id="ooooInterceptors"><ref bean="interceptorTwo" /></util><mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/xxxx/**"/> <ref bean="xxxxInterceptor"/> </mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/oooo/**"/> <ref bean="ooooInterceptor"/> </mvc:interceptor></mvc:interceptors>
好了,关于这一节的内容就说完了。下面笔者来讲一讲为什么拒绝Filter,笔者讲这话的前提是你使用Spring框架。文章的开头说过,Filter是J2EE标准类,如果你用原始的J2EE标准编程的话,使用Filter无可厚非,但这是一个Spring的时代,不是吗?用Servlet类的毕竟是少数,而我希望这个少数越来越少。
期待更多的文章,就关注我吧!
觉得文章写得好的话,支付宝打赏一下吧!
代码详情,请参考我的github 点击打开链接
- 玩转Spring!从拒绝Filter开始
- 玩转示波器从这里开始
- 从玩开始
- 18.玩转Spring Boot 注册Servlet、Filter、Listener
- 玩转centos7(3)--从编程开始
- 《销售从被拒绝开始》叶冠1
- Filter过滤器—从0开始
- 开始拒绝
- 初学者拒绝框架,从Servlet开始学习之路吧!
- 从源码开始编译spring
- Filter拒绝浏览器缓存
- 从今天我开始,我玩Blog了~~
- 从0开始玩安全——安装KALI
- Shiro过滤器(1)-先从filter路径开始讲起
- 【esp8266】从0开始玩转Gokit3 SOC(2)全彩智能灯应用-数值量下发控制
- 【esp8266】从0开始玩转Gokit3 SOC(3)全彩智能灯应用-编译固件
- 熟悉Spring框架,从IOC开始。。。
- Spring从开始到精通HelloSpring
- 位运算初步
- E - 求奇数的乘积
- 1613-3-傅溥衍 总结《2016年11月24日》【连续第五十五天总结】
- Karabiner常用的自带快捷键
- 浏览器返回刷新页面
- 玩转Spring!从拒绝Filter开始
- github 版本回退
- 网易面试题之A,B,C三个人是好朋友,每个人手里都有一些糖果
- TextUtils用法
- C++协程库
- 输入类设备简介
- poj 2996 Help Me with the Game
- 相对路径、根路径、绝对路径的区别
- Python 相对导入