Spring-MVC中的一些问题

3月 22nd, 2016 2,690 留下评论 阅读评论

想法:Spring-mvc(Spring v3.2)中,仅对注册过(通过@RequestMapping注解)的url进入到controller层,其他非法url在Filter里就拦截掉,统一处理节省资源。因为在filter的doChain之前,给本次请求从对象池中获取一个操作db的对象,对无效url也分配的话就浪费了资源。

实现:通过Spring-mvc的RequestMappingHandlerMapping来获取注册过的url path,再根据HttpServletRequest,判断下就可以进行过滤。

自己实现

一开始,自己新建一个类用一个HashMap去保存所有的url path即可,在controller中的static域或者构造方法里,添加本controller中的所有url path即可。

问题一:spring日志显示已经初始化完毕绑定了url了,但是并没有触发controller中的static域或者构造方法!

不得不使用Class.forName()去强制触发static域。

原因:spring-servlet.xml中<beans>根标签加了default-lazy-init=”true”,所有controller在有真正http请求到来才会被访问到!

问题二:spring日志显示明明有url记录,为啥要再自己干?

日志显示一个叫RequestMappingHandlerMapping的东西显然保存了url注册,拿到这个bean的实例应该就大功告成。

通过RequestMappingHandlerMapping

问题三:在Filter里用WebApplicationContextUtils.getWebApplicationContext(ServletContext)的方法拿到ApplicationContext后,但是拿不到bean

这个ApplicationContext里面根本没有任何bean!

原因:这个ApplicationContext是针对applicationContext.xml建出来的Root ApplicationContext,而Spring MVC根据spring-servlet.xml建立的是一个Child ApplicationContext

问题四:在Filter里无法获取到spring-servlet.xml建立的Child ApplicationContext

因为通过Root ApplicationContext拿不到Children,也没有任何API可以直接获取Child ApplicationContext。

原因:Filter是直接注册在web.xml中的,并不归Spring管理,Spring MVC根据spring-servlet.xml建立ApplicationContext只能注入到同一个Spring容器中的bean,比如所有controller中。

于是新建一个类交给Spring管理(在spring-servlet.xml中定义bean),然后implements ApplicationContextAware,就可以获得Spring MVC的ApplicationContext了,自然就拿到了RequestMappingHandlerMapping的bean,将其保存下来,通过判断requestMappingHandlerMapping.getHandler(request) == null即可知道是否为有效url path。

Categories: Java 标签:
  1. 还没有评论呢。