- 浏览: 4250409 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
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 46290Kaptcha是一个基于SimpleC ... -
Unable to locate Spring NamespaceHandler for XML schema namespace
2013-11-05 16:25 59550java服务中整合了spring,在Eclipse里本地启 ... -
由缓存导致的一个java序列化问题
2013-09-24 22:38 11341背景描述: 项目是普 ... -
使用监听器对Spring bean id进行唯一校验
2013-01-23 09:23 6101背景: 项目中 ... -
使用maven插件对java工程进行打包
2012-10-26 17:30 51154现在基本上都是采用maven来进行开发管理,我有一个需求是需要 ... -
java.lang.IllegalStateException:Unable to load schema mappings from location ……
2012-10-10 10:43 8430Java Web工程在启动时报错:java.lang.Ille ... -
JVM学习笔记(九):基于栈的解释器执行过程
2012-07-26 00:37 5128本文根据《深入理解java ... -
JVM学习笔记(八):类加载器以及双亲委派模型介绍
2012-07-19 21:02 7786本章内容根据《深入理解Java虚拟机》第7章部分内容整理 ... -
JVM学习笔记(七):类加载的过程
2012-07-19 18:59 3639本文根据《深入理解java虚拟机》第7章部分内容整理 ... -
JVM学习笔记(六):类加载的时机
2012-07-18 14:58 8616本文根据《深入理解java ... -
JVM学习笔记(五):根据字节码指令介绍方法执行流程
2012-07-17 19:48 2823在上一篇博客中介绍了《Class文件结构》,其中就提 ... -
JVM学习笔记(四):Class文件结构
2012-07-17 18:29 5455本文根据《深入理解Java ... -
JVM学习笔记(三):JVM的垃圾回收
2012-07-12 21:06 4141注:本文根据《深入理解Java虚拟机》第3章部分内容整理而成 ... -
JVM学习笔记(二):JVM中对象访问的两种方式
2012-07-11 18:32 4356由于Reference类型在Java虚拟机规范里面只规定 ... -
JVM学习笔记(一):运行时数据区
2012-07-11 17:31 10592运行时数据区 java虚拟机定义了若干种程序运行时使 ... -
MyBatis批量插入数据
2012-07-10 08:50 433800在程序中封装了一个List集合对象,然后需要把该集合中的实体插 ... -
MySQL报错: java.sql.SQLException: Column count doesn't match value count at row 1
2012-07-09 16:24 28445项目使用了Spring和MyBatis,在往mysql数据库里 ... -
Maven依赖管理
2012-07-08 23:35 4851Maven提供dependencyManagemen ... -
Maven聚合与继承
2012-07-08 23:22 36692Maven聚合与继承 一、聚合 为了能够使用 ... -
java.lang.NoClassDefFoundError: org/aspectj/weaver/BCException
2012-06-18 10:27 30974在项目中使用了Spring管理和配置事务,在启动tom ...
相关推荐
spring mvc 拦截器获取请求数据信息 解压之后放到项目中 直接运行就可以了 (将流多次运用)
spring拦截器,高级参数绑定,controller返回值
springaop拦截controller日志
做一个简单的spring请求过滤,session存在显示,不存在自动跳转指定页面.
Spring Mvc AOP通过注解方式拦截controller等实现日志管理
假定两个Controller都在同一个工程中。 如果有比较合理的分层设计,这样的需求应该是非常...因为Controller B的实例中,Spring Boot为其进行配置和对象注入,这些准备工作不是简单通过实例化Controller B可以完成。
AOP拦截器示例,告诉我们初学者理解aop,通过一个银行转帐说明问题。
spring-boot 拦截器 登录拦截spring-boot 拦截器 登录拦截spring-boot 拦截器 登录拦截spring-boot 拦截器 登录拦截
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 拦截器,可以自定义限制跳转路径及自定义不拦截哪些具体路径,具体设置可以看注释,一看就懂,引用哪些包已经包含了,不明白的请浏览,看到后第一时间给您回复