SpringMVC拦截器中通过反射得到Controller方法注解时ClassCastException解决方案
2015-06-11 16:19
701 查看
错误应用场
在Controller中,我们自定义了一个
@Auth注解来实现权限控制功能,如:
@Auth(verifyLogin=false,verifyURL=false) @RequestMapping("/login") public ModelAndView login(HttpServletRequest request,HttpServletResponse response) throws Exception{ Map<String,Object> context = getRootMap(); return forword("login", context); }
表示该方法不需要登陆验证,也不需要URL权限验证。
AOP. 通过Spring AOP拦截方法调用实现
Interceptor. 注册一个拦截器,在拦截器中通过反射得到被调用的控制器方法的
@Auth注解,从而实现业务功能
显然使用拦截器更方便,代码量更少。看一下拦截器的
preHandle()方法的签名:
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
通过文档得知,第三个参数就是即将调用的控制器方法。于是我们可以通过反射得到
@Auth注解:
HandlerMethod method = (HandlerMethod)handler; Auth auth = method.getMethod().getAnnotation(Auth.class);
但是实际运行中发现很严重的问题,那就是
handler的实际类型并不总是
HandlerMethod类型,因此第一行代码经常会扔
ClassCastException。经过研究发现,只有当GET请求是请求静态文件时(在spring配置文件里会配置静态文件的URI),
handler的实际类型会是
DefaultServletHttpRequestHandler,此时强制转换就会报错。
解决方法
在执行强制转换之前用instanceof检查参数
handler的实际类型,如果不是
HandlerMethod类型,则拦截器不执行任何验证逻辑,直接放行。
为什么要记录一下?因为我发现老外给的Demo中都没有执行类型检查,误导了很多人,让使用者以为
handler一定是
HandlerMethod类型。这里也提醒我们养成良好的编程习惯,执行强制转换之前一定要做类型检查。
相关文章推荐
- 细话Java:"失效"的private修饰符
- java 时间与字符串之间的转换
- 排序算法---基础算法(冒泡排序,快速排序,选择排序,直接插入排序,桶排序)
- MyEclipse使用总结——MyEclipse10安装SVN插件
- java实现图片与base64字符串之间的转换
- Struts1、Struts2、Spring MVC 流程图,对比
- java中Collections.sort() 排序函数的用法
- java ee 基础常识
- java 网格组布局
- javax.ws.rs Annotation Type Encoded
- Eclipse主题和Code颜色主题
- java-从先序遍历和中序遍历重建二叉树
- java计算时间工具类
- eclipse集成jboss7.1
- eclipse学习二 如何导入外部jar包
- Java:String和Date、Timestamp之间的转换
- java类内存中只能运行一个实例对象
- Struts2和Spring整合时使用Struts-plugin的注意点
- org.springframework.web.multipart.MultipartException: The current request is not a multipart request
- struts 2吊牌s:if 、s:iterator注意