springmvc跳转到静态资源

springmvc的入口是DispatcherServlet,在web.xml中的配置一般是拦截所有的请求,作为http请求访问的入口。
springmvc跳转到静态资源
在springvc.xml里做最简单的配置如下:
springmvc跳转到静态资源
在Controller里访问html:
springmvc跳转到静态资源
会发现页面404:
springmvc跳转到静态资源
原因是没有从HandlerMapping里找到对应的handler进行处理。DispatcherServlet拦截所有请求后,对静态资源index.html的访问也被认为是springmvc的请求,而Controller里没有对应的index.htmlRequestMapping进行处理,就报了404.
springmvc跳转到静态资源
解决这个问题,需要在springmvc里配置mvc:default-servlet-handler:
springmvc跳转到静态资源
mvc:default-servlet-handler配置SimpleUrlHandlerMapping和DefaultServletHttpRequestHandler,当springmvc的请求找不到对应处理时,将请求交给web容器配置的默认servlet(defaultServlet)进行处理。

这样配置后会发现还是有问题:
springmvc跳转到静态资源
并且查看日志发现并没有进入Controller:
springmvc跳转到静态资源
其他都没有变,只是配置了mvc:default-servlet-handler,问题应该出在这里:
当没有配置mvc:default-servlet-handler时,springmvc.xml里没有配置任何HandlerMapping,所以springmvc会读取默认的配置,看源码:
springmvc跳转到静态资源
springmvc跳转到静态资源
当配置了mvc:default-servlet-handler时,会隐式的配置一个SimpleUrlHandlerMapping和DefaultServletHttpRequestHandler,这个时候就不会去读取默认的配置;
而配置了mvc:default-servlet-handler之后,所有的请求就都交给了web容器defaultServlet去处理了,相当于没有使用springmvc,Controller里的RequestMapping配置全部失效。

要解决这个问题,就要显式的配置HandlerMapping:
springmvc跳转到静态资源
这里HandlerMapping和HandlerAdapter应该是一一对应成对出现的,如果只配置了HandlerMapping,没有配置HandlerAdapter,会报找不到HandlerAdapter的错误。
配置RequestMappingHandlerMapping,并且order属性置为1.order属性值越小,表示HandlerMapping的匹配顺序越前。
mvc:default-servlet-handler隐式配置的BeanNameUrlHandlerMapping初始化的order为Integer.MAX_SIZE,所以当配置了handlerMapping,将order置为1后,请求会先和RequestMappingHandlerMapping进行匹配处理,当找不到对应的处理时,才会和mvc:default-servlet-handler的配置匹配,交给DefaultServlet处理。
这样,不管是springmvc的映射请求,还是静态资源html的请求,都能够正确处理了:
springmvc跳转到静态资源
这里springmvc.xml显示配置HandlerMapping和HandlerAdapter有一种便捷的方式,使用mvc:annotation-driven标签可以替代。
当配置mvc:annotation-driven标签时,隐式的配置RequestMappingHandlerMapping、RequestMappingHandlerAdapter和ExceptionHandlerExceptionResolver,同时还提供了数据绑定支持,@NumberFormatannotation支持,@DateTimeFormat支持,@Valid支持,读写XML的支持(JAXB,读写JSON的支持(Jackson)等等。
同样可以达到效果,并且更加便捷,提供了更多的功能。