Spring-MVC中的一些问题
想法: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。