基于Spring MVC的Web应用开发(3) - Resources
上一篇介绍了在基于Spring MVC的Web项目中加入日志,本文介绍Spring MVC如何处理资源文件。
注意到本项目的web.xml配置的DispatcherServlet对应的url-pattern为"/",即所有的URL请求都会经过Spring MVC的处理。实际的Web项目有大量的资源文件,如javascript文件,css文件,png,jpg等图片文件,甚至是Flash等等,我们没有必要对这些静态文件的访问都设置对应的URL,那样会造成大量重复性的劳动,以及维护上的复杂性。Spring MVC提供了一种机制,可以映射一种URL和一个location,此URL后面接的静态文件,对应着location目录下对应的静态文件。此配置为:
说明一下,
1. 访问http://localhost:8080/resources/test.png,浏览器显示webapp/resources/test.png
2. 访问http://localhost:8080/resources/scripts/test.js,浏览器显示webapp/resources/scripts/test.js
3. 访问http://localhost:8080/resources/css/2012/test.css,浏览器显示webapp/resources/css/2012/test.css
注意到mapping的值"/resources/**"有两个*,它表示映射resources/下所有的URL,包括子路径(即接多个/),如上面的1、2、3,如果只有一个*,将只能映射1级路径,即只能访问1,访问2、3将会报错。
很遗憾,如果只加这一行,带有@Controller类里面的@RequestMapping映射都不会生效。我是搜索到stackoverflow上的这个帖子联想到解决方案的,后来在stackoverflow搜到另外一个帖子有个还算比较详细的解释,帖子上说使用<mvc:resources/>时必须添加<mvc:annotation-driven/>,然后带有@Controller注解类的@RequestMapping映射信息才能被读取到。
现在servlet-context.xml为:
访问http://localhost:8080/web/resources/test.js,浏览器上显示的正是test.js的内容。
?
下面解决HelloWorld那篇文章中遗留的一个问题,在那一篇文章中,@RequestMapping只有一个"/simple",但从日志中发现,有三种URL"/simple","/simple.*","/simple/"映射
不再是DefaultAnnotationHandlerMapping,而换成了RequestMappingHandlerMapping。
我们改变一下思路,从请求端看看SpringMVC如何处理上面说的三种URL。
访问http://localhost:8080/web/simple
下面对处理资源的配置可以满足刚才说的一年后的实验性特性,确保了浏览器缓存的最大化使用率和减少浏览器发起的HTTP请求:
?mapping这个属性必须是一个Ant模式(不太清楚什么是Ant模式 译者),该Ant模式可以被SimpleHandlerMapping使用,location属性必须指定一个或者多个有效的资源目录位置。多个资源位置可以通过使用逗号分隔符的列表值指定。指定的位置会根据任何给定的请求的资源的表现,按照一个特定的顺序被检查一遍。比如为了使我们即能访问web应用root路径又能访问classpath路径下任何一个jar包里一个已知的/META-INF/public-web-resources/路径,我们这样写:
当资源有可能随着新版本的应用的发布而改变时,推荐你将一个版本字符串放进请求资源时使用的映射模式中,因此你可以强制客户端请求应用资源中部署的新版本。这样一个版本字符串使用SpEL配置,因此当部署新版本时,它可以很容易的在单个地方管理起来。
举个例子,我们考虑一个应用,它在生产环境使用一个性能优化过的定制的Dojo JavaScript库的构件,这个构件通常在一个web应用中的/public-resources/dojo/dojo.js路径下部署。因为对于应用的每个新版本,Dojo的不同部分可能会合并成一个定制构件,客户端浏览器需要强制性的重新下载定制构件dojo.js资源,只要一个新版本的应用被部署了。一个简单的打包方式就是在一个.properties配置文件中管理应用的版本,比如:
现在通过SpEL,application.version可以访问了,我们可以将它合并到<resource/>标签里。
?在Java类中,你可以使用@PropertiesSource注解,然后注入Environment抽象类,来访问到所有预定义的属性值:
最后,为了使用合适的URL请求资源,我们可以利用Spring JSP标签:(在JSP页面中使用的 译者)
??
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?