如何从abstracthandlermapping对象中获取handlermethod对象

如何从abstracthandlermapping对象中获取handlermethod对象,第1张

Spring拦截器中通过request获取到该请求对应于Controller中的目标method方法对象。Controller和拦截器代码如下:

AdminController

Java代码
@Controller
@RequestMapping("/admin")
public class AdminController {

/
init:初始页面 <br/>

@author chenzhou
@param request 请求
@param response 响应
@return 登陆页
@since JDK 16
/
@RequestMapping("/init")
public ModelAndView init(HttpServletRequest request,
HttpServletResponse response){
Map<String, Object> model = new HashMap<String, Object>();
List<Role> roleList = thisadminServicegetRoleList();
modelput("roleList", roleList);
return new ModelAndView(thisgetLoginPage(), model);
}

//……
}
LoginInterceptor

Java代码
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配置文件定义:
Xml代码
<bean class="orgspringframeworkaopaspectjannotationAnnotationAwareAspectJAutoProxyCreator" />
<bean class="orgspringframeworkwebservletmvcannotationAnnotationMethodHandlerAdapter"/>
<bean class="orgspringframeworkwebservletmvcannotationDefaultAnnotationHandlerMapping">
<property name="interceptors">
<list>
<bean class="comchenzhouexamplesermutilinterceptorLoginInterceptor"/>
</list>
</property>
</bean>
我的需求是想在preHandle方法中通过request获取该请求访问的目标Controller中的方法对象。之前找了很久也没有找到比较好的方案,就采取了最老土的通过比较requestURL和Controller类和方法上的RequestMappingURL来进行获取,这样也能勉强实现,但是这种方式我自己都觉得特别恶心。首先,这种方式需要使用反射来获取Controller中的所有方法,然后遍历method数组,逐个进行RequestMappingURL的比对,效率低下。其次,如果RequestMapping定义了类似于@RequestMapping("/{id}")这种动态参数url,则无法进行比较。
因为上面这种方式不好,我就一直想找一个更好的方案。不得已只能向人求助,第一个就想到了Iteye上对于Spring研究得很熟悉的jinnianshilongnian龙年兄,我相信经常上iteye的博友们对龙年兄应该都很熟悉。龙年兄给了我一个方案,就是通过把handler对象转换为HandlerMethod类型,然后直接getMethod,代码如下:

Java代码
/
This implementation always returns <code>true</code>
/
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
Systemoutprintln("preHandle");
Systemoutprintln(handlergetClass());
HandlerMethod handlerMethod = (HandlerMethod) handler;
Systemoutprintln(handlerMethodgetMethod());
return true;
}

注:HandlerMethod类是Spring 310RELEASE版本中才有的,之前我使用的Spring 306RELEASE版本,里面是找不到这个类的

根据龙年兄提供的方法,测试之后报错,报错信息如下:

Shell代码
preHandle
class comchenzhouexamplesermwebAdminController
2012-10-21 16:28:25 orgapachecatalinacoreStandardWrapperValve invoke
严重: Servletservice() for servlet erm threw exception
javalangClassCastException: comchenzhouexamplesermwebAdminController cannot be cast to orgspringframeworkwebmethodHandlerMethod
at comchenzhouexamplesermutilinterceptorLoginInterceptorpreHandle(LoginInterceptorjava:37)
at orgspringframeworkwebservletDispatcherServletdoDispatch(DispatcherServletjava:891)
at orgspringframeworkwebservletDispatcherServletdoService(DispatcherServletjava:827)
at orgspringframeworkwebservletFrameworkServletprocessRequest(FrameworkServletjava:882)
at orgspringframeworkwebservletFrameworkServletdoGet(FrameworkServletjava:778)
at javaxservlethttpHttpServletservice(HttpServletjava:617)
at javaxservlethttpHttpServletservice(HttpServletjava:717)
……

根据错误提示可以看出是HandlerMethod handlerMethod = (HandlerMethod) handler;这一步报错了,根据Systemoutprintln(handlergetClass());打印的结果可以得知handler是该请求访问的Controller类,无法转换成HandlerMethod对象。这次还是龙年兄帮我找出了原因,解决方案是使用
<bean class="orgspringframeworkwebservletmvcmethodannotationRequestMappingHandlerMapping">
替换
<bean class="orgspringframeworkwebservletmvcannotationDefaultAnnotationHandlerMapping"/>
因为DefaultAnnotationHandlerMapping只能返回Controller对象,不会映射到Controller中的方法级别。替换之后servlet xml配置如下:

Xml代码
<bean class="orgspringframeworkaopaspectjannotationAnnotationAwareAspectJAutoProxyCreator" />
<bean class="orgspringframeworkwebservletmvcannotationAnnotationMethodHandlerAdapter"/>
<bean class="orgspringframeworkwebservletmvcmethodannotationRequestMappingHandlerMapping">
<property name="interceptors">
<list>
<bean class="comchenzhouexamplesermutilinterceptorLoginInterceptor"/>
</list>
</property>
</bean>

重启tomcat测试之后发现再次报错,报了另外一个错误,具体信息如下:

Shell代码
2012-10-21 16:39:39 orgapachecatalinacoreStandardWrapperValve invoke
严重: Servletservice() for servlet erm threw exception
javaxservletServletException: No adapter for handler [public orgspringframeworkwebservletModelAndView comchenzhouexamplesermwebAdminControllerinit(javaxservlethttpHttpServletRequest,javaxservlethttpHttpServletResponse)]: Does your handler implement a supported interface like Controller
……

这一次,请求根本没有到达拦截器容器就已经报错了,错误提示的意思是找不到handler对象对应的Adapter类。我在RequestMappingHandlerMapping类对应的spring-webmvc-310RELEASEjar 包里找到了该类对应的Adapter类:RequestMappingHandlerAdapter,然后在servlet xml中进行了配置:

Xml代码
<bean class="orgspringframeworkaopaspectjannotationAnnotationAwareAspectJAutoProxyCreator" />
<bean class="orgspringframeworkwebservletmvcannotationAnnotationMethodHandlerAdapter"/>
<bean class="orgspringframeworkwebservletmvcmethodannotationRequestMappingHandlerMapping">
<property name="interceptors">
<list>
<bean class="comchenzhouexamplesermutilinterceptorLoginInterceptor"/>
</list>
</property>
</bean>
<bean class="orgspringframeworkwebservletmvcmethodannotationRequestMappingHandlerAdapter"/>

然后重新启动tomcat后访问http://localhost:8080/erm/admin/init 结果正常,控制台日志信息如下:
Shell代码
preHandle
class orgspringframeworkwebmethodHandlerMethod
public orgspringframeworkwebservletModelAndView comchenzhouexamplesermwebAdminControllerinit(javaxservlethttpHttpServletRequest,javaxservlethttpHttpServletResponse)
从日志信息可以看出,handler对象在经过类型转换后转换成了HandlerMethod类型,通过handlergetMethod方法,获取到了该请求访问的方法为comchenzhouexamplesermwebAdminControllerinit

以上就是关于如何从abstracthandlermapping对象中获取handlermethod对象全部的内容,包括:如何从abstracthandlermapping对象中获取handlermethod对象、、等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/web/10094115.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-05
下一篇 2023-05-05

发表评论

登录后才能评论

评论列表(0条)

保存