Spring资源访问机制
2014-04-11 21:57
393 查看
本文介绍Spring中提供的资源访问机制。
JDK所提供的访问资源的类(如java.net.URL、File等)并不能很好地满足各种底层资源的访问需求,比如缺少从类路径或者Web容器的上下文中获取资源的操作类。有鉴于此,Spring设计了一个Resource接口,它为应用提供了更强的访问底层资源的能力。该接口拥有对应不同资源类型的实现类。先来了解一下Resource接口的主要方法:
● boolean exists():资源是否存在;
● boolean isOpen():资源是否打开;
● URL getURL() throws IOException:如果底层资源可以表示成URL,该方法返回对应的URL对象;
● File getFile() throws IOException:如果底层资源对应一个文件,该方法返回对应的File对象;
● InputStream getInputStream() throws IOException:返回资源对应的输入流。
Spring框架使用Resource装载各种资源,这些资源包括配置文件资源、国际化属性文件资源等。如下为Resource的具体实现类关系图:
● ByteArrayResource:二进制数组表示的资源,二进制数组资源可以在内存中通过程序构造;
● ClassPathResource:类路径下的资源,资源以相对于类路径的方式表示;
● FileSystemResource:文件系统资源,资源以文件系统路径的方式表示,如D:/conf/bean.xml等;
● InputStreamResource:以输入流返回表示的资源;
● ServletContextResource:为访问Web容器上下文中的资源而设计的类,负责以相对于Web应用根目录的路径加载资源,它支持以流和URL的方式访问,在WAR解包的情况下,也可以通过File的方式访问,该类还可以直接从JAR包中访问资源;
● UrlResource:Url封装了java.net.URL,它使用户能够访问任何可以通过URL表示的资源,如文件系统的资源、HTTP资源、FTP资源等。
代码示例:
资源加载时默认采用系统编码读取资源内容,如果资源文件采用特殊的编码格式,那么可以通过EncodedResource对资源进行编码,以保证资源内容操作的正确性:
代码示例:
为了访问不同类型的资源,必须使用相应的Resource实现类,这是比较麻烦的。是否可以在不显式使用Resource实现类的情况下,仅通过资源地址的特殊标识就可以加载相应的资源呢?Spring提供了一个强大加载资源的机制,不但能够通过"classpath:"、"file:"等资源地址前缀识别不同的资源类型,还支持Ant风格带通配符的资源地址。
Spring支持哪些资源类型的地址前缀:
其中和"classpath:"对应的,还有另一种比较难理解的"classpath*:"前缀。假设有多个JAR包或文件系统类路径都拥有一个相同的包名(如com.coder)。"classpath:"只会在第一个加载的com.coder包下查找,而"classpath*:"会到扫描所有这些JAR包及类路径下出现的com.coder类路径。
Ant风格资源地址支持3种匹配符:
● ?:匹配文件名中的一个字符;
● *:匹配文件名中任意个字符;
● **:匹配多层路径。
下面是几个Ant风格的资源路径的示例:
● classpath:com/t?st.xml :匹配com类路径下com/test.xml,com/tast.xml或者com/txst.xml;
● file:D:/conf/*.xml:匹配文件系统D:/conf目录下所有以xml为后缀的文件;
● classpath:com/**/test.xml:匹配com类路径下(当前目录及其子孙目录)的test.xml文件;
● classpath:org/springframework/**/*.xml:匹配类路径org/springframework下所有以xml为后缀的文件;
● classpath:org/**/servlet/bla.xml:匹配类路径org/springframework/servlet/bla.xml,也匹配org/springframework/testing/servlet/bla.xml,还匹配org/servlet/bla.xml。
Spring定义一套资源加载的接口,并提供了实现类(下图)
代码示例:
资源抽象接口
JDK所提供的访问资源的类(如java.net.URL、File等)并不能很好地满足各种底层资源的访问需求,比如缺少从类路径或者Web容器的上下文中获取资源的操作类。有鉴于此,Spring设计了一个Resource接口,它为应用提供了更强的访问底层资源的能力。该接口拥有对应不同资源类型的实现类。先来了解一下Resource接口的主要方法:● boolean exists():资源是否存在;
● boolean isOpen():资源是否打开;
● URL getURL() throws IOException:如果底层资源可以表示成URL,该方法返回对应的URL对象;
● File getFile() throws IOException:如果底层资源对应一个文件,该方法返回对应的File对象;
● InputStream getInputStream() throws IOException:返回资源对应的输入流。
Spring框架使用Resource装载各种资源,这些资源包括配置文件资源、国际化属性文件资源等。如下为Resource的具体实现类关系图:
● ByteArrayResource:二进制数组表示的资源,二进制数组资源可以在内存中通过程序构造;
● ClassPathResource:类路径下的资源,资源以相对于类路径的方式表示;
● FileSystemResource:文件系统资源,资源以文件系统路径的方式表示,如D:/conf/bean.xml等;
● InputStreamResource:以输入流返回表示的资源;
● ServletContextResource:为访问Web容器上下文中的资源而设计的类,负责以相对于Web应用根目录的路径加载资源,它支持以流和URL的方式访问,在WAR解包的情况下,也可以通过File的方式访问,该类还可以直接从JAR包中访问资源;
● UrlResource:Url封装了java.net.URL,它使用户能够访问任何可以通过URL表示的资源,如文件系统的资源、HTTP资源、FTP资源等。
代码示例:
1 | String filePath = "D:/coder/WebRoot/WEB-INF/classes/conf/file1.txt" ; |
2 | //①使用系统文件路径方式加载文件 |
3 | Resource res1 = new FileSystemResource(filePath); |
4 | //②使用类路径方式加载文件 |
5 | Resource res2 = new ClassPathResource( "conf/file1.txt" ); |
6 | InputStream ins1 = res1.getInputStream(); |
7 | InputStream ins2 = res2.getInputStream(); |
8 | System.out.println( "res1:" +res1.getFilename()); |
9 | System.out.println( "res2:" +res2.getFilename()); |
01 | <%@ page language= "java" contentType= "text/html; charset=utf-8" pageEncoding= "utf-8" %> |
02 | <jsp:directive.page import= "org.springframework.web.context.support.ServletContextResource" /> |
03 | <jsp:directive.page import= "org.springframework.core.io.Resource" /> |
04 | <jsp:directive.page import= "org.springframework.web.util.WebUtils" /> |
05 | <% |
06 | //①注意文件资源地址以相对于Web应用根路径的方式表示 |
07 | Resource res3 = new ServletContextResource(application, "/WEB-INF/classes/conf/file1.txt" ); |
08 | out.print(res3.getFilename()+ "<br/>" ); |
09 | out.print(WebUtils.getTempDir(application).getAbsolutePath()); |
10 | %> |
代码示例:
1 | Resource res = new ClassPathResource( "conf/file1.txt" ); |
2 | EncodedResource encRes = new EncodedResource(res, "UTF-8" ); |
3 | String content = FileCopyUtils.copyToString(encRes.getReader()); |
4 | System.out.println(content); |
资源加载
为了访问不同类型的资源,必须使用相应的Resource实现类,这是比较麻烦的。是否可以在不显式使用Resource实现类的情况下,仅通过资源地址的特殊标识就可以加载相应的资源呢?Spring提供了一个强大加载资源的机制,不但能够通过"classpath:"、"file:"等资源地址前缀识别不同的资源类型,还支持Ant风格带通配符的资源地址。
资源地址表达式
Spring支持哪些资源类型的地址前缀:地址前缀 | 示 例 | 对应资源类型 |
classpath: | classpath:com/coder/beanfactory/beans.xml | 从类路径中加载资源,classpath:和classpath:/是等价的,都是相对于类的根路径。资源文件可以在标准的文件系统中,也可以在jar或zip的类包中 |
file: | file:/conf/com/coder/beanfactory/beans.xml | 使用UrlResource从文件系统目录中装载资源,可采用绝对或相对路径 |
http:// | http: //www.coder.xxx/resource/beans.xml | 使用UrlResource从Web服务器中装载资源 |
ftp:// | ftp: //www.coder.xxx/resource/beans.xml | 使用UrlResource从FTP服务器中装载资源 |
没有前缀 | com/coder/beanfactory/beans.xml | 根据ApplicationContext具体实现类采用对应的类型的Resource |
Ant风格资源地址支持3种匹配符:
● ?:匹配文件名中的一个字符;
● *:匹配文件名中任意个字符;
● **:匹配多层路径。
下面是几个Ant风格的资源路径的示例:
● classpath:com/t?st.xml :匹配com类路径下com/test.xml,com/tast.xml或者com/txst.xml;
● file:D:/conf/*.xml:匹配文件系统D:/conf目录下所有以xml为后缀的文件;
● classpath:com/**/test.xml:匹配com类路径下(当前目录及其子孙目录)的test.xml文件;
● classpath:org/springframework/**/*.xml:匹配类路径org/springframework下所有以xml为后缀的文件;
● classpath:org/**/servlet/bla.xml:匹配类路径org/springframework/servlet/bla.xml,也匹配org/springframework/testing/servlet/bla.xml,还匹配org/servlet/bla.xml。
资源加载器
Spring定义一套资源加载的接口,并提供了实现类(下图)代码示例:
1 | ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); |
2 | //①加载所有类包com.baobaotao(及子孙包)下的以xml为后缀的资源 |
3 | Resource resources[] =resolver.getResources( "classpath*:com/coder/**/*.xml" ); |
4 | for (Resource resource:resources){ |
5 | System.out.println(resource.getDescription()); |
6 | } |
相关文章推荐
- springboot jsp 静态资源访问
- Spring -- 资源访问(二)
- SpringMvc 访问静态资源 出现[org.springframework.web.servlet.PageNotFound]Request method 'GET' not supported
- Spring 资源访问剖析和策略模式应用
- 访问不存在的Thymeleaf 资源时使页面转向 404,而不是500 (Spring Boot)
- Spring 资源访问利器
- Spring之资源访问利器Resource
- spring 第9天 Resurce 资源访问
- Spring 资源访问剖析和策略模式应用
- Spring4 Spring MVC实战(三)——Spring MVC不通过xml配置访问HMTL和其他静态资源
- Spring Boot 设置静态资源访问
- Spring -- 资源访问(二)
- spring资源访问Resource类
- Spring资源访问
- SpringBoot集成Jersey时无法访问静态资源的解决方法
- Spring 学习日记——访问静态资源
- 【第四章】 资源 之 4.3 访问Resource ——跟我学spring3
- 【第四章】 资源 之 4.3 访问Resource ——跟我学spring3
- 09-spring学习-资源访问接口
- Spring源码分析——资源访问利器Resource之接口和抽象类分析