- 浏览: 4249840 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
masuweng:
...
kaptcha验证码组件使用简介 -
caobingyi:
你好,问下html是怎么调用loginCheck方法的?
kaptcha验证码组件使用简介 -
hayoouch:
XieFuQ 写道既然都考虑到乐观锁了,是否可以直接换表存储引 ...
mysql乐观锁总结和实践 -
murdonson:
辛苦了
mysql悲观锁总结和实践 -
iamnotstar:
写得不错,感谢分享
memcached-session-manager配置
背景:项目使用Spring 3.1.0.RELEASE,从dao到Controller层全部是基于注解配置。我的需求是想在自定义的Spring拦截器中通过request获取到该请求对应于Controller中的目标method方法对象。Controller和拦截器代码如下:
AdminController
@Controller @RequestMapping("/admin") public class AdminController { /** * init:初始页面. <br/> * * @author chenzhou * @param request 请求 * @param response 响应 * @return 登陆页 * @since JDK 1.6 */ @RequestMapping("/init") public ModelAndView init(HttpServletRequest request, HttpServletResponse response){ Map<String, Object> model = new HashMap<String, Object>(); List<Role> roleList = this.adminService.getRoleList(); model.put("roleList", roleList); return new ModelAndView(this.getLoginPage(), model); } //…… }
LoginInterceptor
public class LoginInterceptor extends HandlerInterceptorAdapter { /** * This implementation always returns <code>true</code>. */ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return true; } /** * This implementation is empty. */ public void postHandle( HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } /** * This implementation is empty. */ public void afterCompletion( HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } }
servlet xml配置文件定义:
<bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" /> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/> <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> <property name="interceptors"> <list> <bean class="com.chenzhou.examples.erm.util.interceptor.LoginInterceptor"/> </list> </property> </bean>
我的需求是想在preHandle方法中通过request获取该请求访问的目标Controller中的方法对象。之前找了很久也没有找到比较好的方案,就采取了最老土的通过比较requestURL和Controller类和方法上的RequestMappingURL来进行获取,这样也能勉强实现,但是这种方式我自己都觉得特别恶心。首先,这种方式需要使用反射来获取Controller中的所有方法,然后遍历method数组,逐个进行RequestMappingURL的比对,效率低下。其次,如果RequestMapping定义了类似于@RequestMapping("/{id}")这种动态参数url,则无法进行比较。
因为上面这种方式不好,我就一直想找一个更好的方案。不得已只能向人求助,第一个就想到了Iteye上对于Spring研究得很熟悉的jinnianshilongnian龙年兄,我相信经常上iteye的博友们对龙年兄应该都很熟悉。龙年兄给了我一个方案,就是通过把handler对象转换为HandlerMethod类型,然后直接getMethod,代码如下:
/** * This implementation always returns <code>true</code>. */ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("*********************preHandle********************"); System.out.println(handler.getClass()); HandlerMethod handlerMethod = (HandlerMethod) handler; System.out.println(handlerMethod.getMethod()); return true; }
注:HandlerMethod类是Spring 3.1.0.RELEASE版本中才有的,之前我使用的Spring 3.0.6.RELEASE版本,里面是找不到这个类的
根据龙年兄提供的方法,测试之后报错,报错信息如下:
*********************preHandle******************** class com.chenzhou.examples.erm.web.AdminController 2012-10-21 16:28:25 org.apache.catalina.core.StandardWrapperValve invoke 严重: Servlet.service() for servlet erm threw exception java.lang.ClassCastException: com.chenzhou.examples.erm.web.AdminController cannot be cast to org.springframework.web.method.HandlerMethod at com.chenzhou.examples.erm.util.interceptor.LoginInterceptor.preHandle(LoginInterceptor.java:37) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:891) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:827) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778) at javax.servlet.http.HttpServlet.service(HttpServlet.java:617) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) ……
根据错误提示可以看出是HandlerMethod handlerMethod = (HandlerMethod) handler;这一步报错了,根据System.out.println(handler.getClass());打印的结果可以得知handler是该请求访问的Controller类,无法转换成HandlerMethod对象。这次还是龙年兄帮我找出了原因,解决方案是使用
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
替换
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
因为DefaultAnnotationHandlerMapping只能返回Controller对象,不会映射到Controller中的方法级别。替换之后servlet xml配置如下:
<bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" /> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"> <property name="interceptors"> <list> <bean class="com.chenzhou.examples.erm.util.interceptor.LoginInterceptor"/> </list> </property> </bean>
重启tomcat测试之后发现再次报错,报了另外一个错误,具体信息如下:
2012-10-21 16:39:39 org.apache.catalina.core.StandardWrapperValve invoke 严重: Servlet.service() for servlet erm threw exception javax.servlet.ServletException: No adapter for handler [public org.springframework.web.servlet.ModelAndView com.chenzhou.examples.erm.web.AdminController.init(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)]: Does your handler implement a supported interface like Controller? ……
这一次,请求根本没有到达拦截器容器就已经报错了,错误提示的意思是找不到handler对象对应的Adapter类。我在RequestMappingHandlerMapping类对应的spring-webmvc-3.1.0.RELEASE.jar 包里找到了该类对应的Adapter类:RequestMappingHandlerAdapter,然后在servlet xml中进行了配置:
<bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator" /> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"> <property name="interceptors"> <list> <bean class="com.chenzhou.examples.erm.util.interceptor.LoginInterceptor"/> </list> </property> </bean> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
然后重新启动tomcat后访问http://localhost:8080/erm/admin/init 结果正常,控制台日志信息如下:
*********************preHandle******************** class org.springframework.web.method.HandlerMethod public org.springframework.web.servlet.ModelAndView com.chenzhou.examples.erm.web.AdminController.init(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
从日志信息可以看出,handler对象在经过类型转换后转换成了HandlerMethod类型,通过handler.getMethod方法,获取到了该请求访问的方法为com.chenzhou.examples.erm.web.AdminController.init
注:非常感谢jinnianshilongnian 开涛兄的帮助。
评论
org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser A BeanDefinitionParser that provides the configuration for the <annotation-driven/> MVC namespace element. This class registers the following HandlerMappings: RequestMappingHandlerMapping ordered at 0 for mapping requests to annotated controller methods. BeanNameUrlHandlerMapping ordered at 2 to map URL paths to controller bean names. 意思是AnnotationDrivenBeanDefinitionParser类对<annotation-driven/>配置进行 解析, 解析注册两个类,其中一个是RequestMappingHandlerMapping 所以只需要配置<mvc:annotation-driven/>即启用了RequestMappingHandlerMapping基于方法级别的拦截
然后:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.xxx.xxx.xxx.Interceptor"/>
</mvc:interceptor>
</mvc:interceptors>
请楼主帮忙分析
三个拦截器处理三个注解搞定基于注解的权限控制,适用性比较通用于Springmvc web项目
<bean id="jsonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>text/html;charset=UTF-8</value> <value>text/plain;charset=UTF-8</value> <value>application/json; charset=UTF-8</value> <value>application/x-www-form-urlencoded; charset=UTF-8</value> </list> </property> </bean>但还是没用
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.chenzhou.examples.erm.util.interceptor.LoginInterceptor"></bean> </mvc:interceptor> </mvc:interceptors>
其中path可以修改一下,改成你需要的地址就行。
也可以这么说吧,当时是为了做权限控制发现aop对Controller不生效,后来就采用了拦截器的方式。
不客气
谢谢鼓励
这种方式的分享让人受益很大。
谢谢鼓励!
这种方式的分享让人受益很大。
可以试下下面方法:
Class handlerClass = ClassUtils.getUserClass(handler); ServletHandlerMethodResolver resolver = new ServletHandlerMethodResolver(handlerClass); Method handlerMethod = methodResolver.resolveHandlerMethod(request);
呵呵,抱歉没注意到ServletHandlerMethodResolver是一个内部私有类
发表评论
-
kaptcha验证码组件使用简介
2013-12-10 11:53 46281Kaptcha是一个基于SimpleC ... -
Unable to locate Spring NamespaceHandler for XML schema namespace
2013-11-05 16:25 59543java服务中整合了spring,在Eclipse里本地启 ... -
由缓存导致的一个java序列化问题
2013-09-24 22:38 11335背景描述: 项目是普 ... -
使用监听器对Spring bean id进行唯一校验
2013-01-23 09:23 6098背景: 项目中 ... -
使用maven插件对java工程进行打包
2012-10-26 17:30 51148现在基本上都是采用maven来进行开发管理,我有一个需求是需要 ... -
java.lang.IllegalStateException:Unable to load schema mappings from location ……
2012-10-10 10:43 8426Java Web工程在启动时报错:java.lang.Ille ... -
JVM学习笔记(九):基于栈的解释器执行过程
2012-07-26 00:37 5126本文根据《深入理解java ... -
JVM学习笔记(八):类加载器以及双亲委派模型介绍
2012-07-19 21:02 7780本章内容根据《深入理解Java虚拟机》第7章部分内容整理 ... -
JVM学习笔记(七):类加载的过程
2012-07-19 18:59 3636本文根据《深入理解java虚拟机》第7章部分内容整理 ... -
JVM学习笔记(六):类加载的时机
2012-07-18 14:58 8609本文根据《深入理解java ... -
JVM学习笔记(五):根据字节码指令介绍方法执行流程
2012-07-17 19:48 2820在上一篇博客中介绍了《Class文件结构》,其中就提 ... -
JVM学习笔记(四):Class文件结构
2012-07-17 18:29 5452本文根据《深入理解Java ... -
JVM学习笔记(三):JVM的垃圾回收
2012-07-12 21:06 4137注:本文根据《深入理解Java虚拟机》第3章部分内容整理而成 ... -
JVM学习笔记(二):JVM中对象访问的两种方式
2012-07-11 18:32 4353由于Reference类型在Java虚拟机规范里面只规定 ... -
JVM学习笔记(一):运行时数据区
2012-07-11 17:31 10583运行时数据区 java虚拟机定义了若干种程序运行时使 ... -
MyBatis批量插入数据
2012-07-10 08:50 433796在程序中封装了一个List集合对象,然后需要把该集合中的实体插 ... -
MySQL报错: java.sql.SQLException: Column count doesn't match value count at row 1
2012-07-09 16:24 28439项目使用了Spring和MyBatis,在往mysql数据库里 ... -
Maven依赖管理
2012-07-08 23:35 4847Maven提供dependencyManagemen ... -
Maven聚合与继承
2012-07-08 23:22 36683Maven聚合与继承 一、聚合 为了能够使用 ... -
java.lang.NoClassDefFoundError: org/aspectj/weaver/BCException
2012-06-18 10:27 30972在项目中使用了Spring管理和配置事务,在启动tom ...
相关推荐
spring mvc 拦截器获取请求数据信息 解压之后放到项目中 直接运行就可以了 (将流多次运用)
spring拦截器,高级参数绑定,controller返回值
springaop拦截controller日志
做一个简单的spring请求过滤,session存在显示,不存在自动跳转指定页面.
Spring Mvc AOP通过注解方式拦截controller等实现日志管理
AOP拦截器示例,告诉我们初学者理解aop,通过一个银行转帐说明问题。
spring-boot 拦截器 登录拦截spring-boot 拦截器 登录拦截spring-boot 拦截器 登录拦截spring-boot 拦截器 登录拦截
假定两个Controller都在同一个工程中。 如果有比较合理的分层设计,这样的需求应该是非常...因为Controller B的实例中,Spring Boot为其进行配置和对象注入,这些准备工作不是简单通过实例化Controller B可以完成。
Spring AOP 拦截器 Advisor Spring AOP 拦截器 Advisor
常用拦截 拦截器HandlerInterceptor 拦截器MethodInterceptor 添加依赖 创建启动类 创建拦截器类 创建控制器 监控control请求耗时,提高性能
Spring MVC 拦截器Spring MVC 拦截器
NULL 博文链接:https://lpm528.iteye.com/blog/1259187
初学者很容易将 Spring MVC 拦截器 和 Spring Cloud OpenFeign 拦截器搞混,误以为OpenFeign拦截器就是SpringMVC拦截器:Spring MVC拦截器发生在客户端 和 服务端之间,在客户端向服务端发送请求时进行拦截处理。...
使用CGLIB编写的Spring的拦截器 非常使用的哦
NULL 博文链接:https://rogerhunt.iteye.com/blog/608778
spring boot jpa连接数据库,设置拦截器拦截指定路径下的文件。
idea软件。SpringBoot的拦截器的博客所写的例子。preHandle()方法的返回值true和false的详细区别还未描述
这一版本的项目中新增了拦截器的一个demo
自己spring boot 拦截器,可以自定义限制跳转路径及自定义不拦截哪些具体路径,具体设置可以看注释,一看就懂,引用哪些包已经包含了,不明白的请浏览,看到后第一时间给您回复