概述
虽然JDK提供了访问资源的类如java.net.URL,File等,但是并不能很好的满足各底层访问资源的需求,如:并没有直接提供类路径或者web上下文资源的访问类。鉴于此Spring提供了访问资源的Resource接口,它为应用提供了访问底层资源的能力。Resource在Spring中起着不可或缺的作用,Spring框架通过Resource来加载各种资源,如配置文件资源、国际化属性资源等。而且Spring的Resource还可以脱离框架来使用,我们只需要引入Spring的core jar包即可使用这些功能。
Resource只是个接口,它和其实现类的结构如下:
常用到的一些实现类介绍:
ByteArrayResource:访问二进制数组表示的资源。
ClassPathResource:访问类路径下的资源,这个是比较常用的。
FileSystemResource:访问系统资源。
InputStreamResource:访问一个InputStreamResource资源。
UrlResource:封装了java.net.URL使用户能够访问任何以URL表示的资源。
一个简单实例,这里只是引用了Spring的core jar包,并没有使用整个Spring框架:
package cn.qing.spring.resource;
import java.io.IOException;
import java.util.Properties;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.util.FileCopyUtils;
public class TestSpringResource {
/**
* @param args
*/
public static void main(String[] args) {
//使用ClassPathResource来加载类路劲下的资源
Resource classPathResource = new ClassPathResource("resource.properties");
//使用FileSystemResource来加载系统文件资源
Resource fileSystemResource = new FileSystemResource("F:/myEclipseProject/spring/WebRoot/WEB-INF/classes/resource.properties");
Properties properties = new Properties();
try {
System.out.println("***************************classPathResource*************************");
properties.load(classPathResource.getInputStream());
System.out.println("host:"+properties.getProperty("host") + "\t port:"+properties.getProperty("port")+"\t context:"+properties.getProperty("context", "default"));
properties.clear();
System.out.println("****************************fileSystemResource************************");
properties.load(fileSystemResource.getInputStream());
System.out.println("host:"+properties.getProperty("host") + "\t port:"+properties.getProperty("port")+"\t context:"+properties.getProperty("context", "default"));
System.out.println("****************************readXml************************");
classPathResource = new ClassPathResource("xmlresource.xml");
//对资源进行编码
EncodedResource encodedResource = new EncodedResource(classPathResource,"UTF-8");
//使用FileCopyUtils.copyToString获取资源文件中的内容
String content = FileCopyUtils.copyToString(encodedResource.getReader());
System.out.println(content);
} catch (IOException e) {
e.printStackTrace();
}
}
}
其中resource.properties和xmlresource.xml都是放在src下的资源。
输出结果:
***************************classPathResource*************************
host:192.168.0.1 port:8080 context:spring
****************************fileSystemResource************************
host:192.168.0.1 port:8080 context:spring
****************************readXml************************
<?xml version="1.0" encoding="UTF-8"?>
<xml-body>
<beans>
<bean id="test" class="cn.qing.java.Test"/>
</beans>
</xml-body>
上面使用ClassPathResource和FileSystemResource都可以正常访问到我们需要的资源,像这种访问不同的资源,都必须需要使用不同的Resource资源类,才能够正常访问对应的资源。其实Spring还提供了一个强大的资源加载机制,可以通过"classpath:"、"file:"等资源地址前缀来访问资源,这种访问方式还支持通配符的方式。
Spring提供的资源地址前缀:
classpath: 用于加载类路径资源
使用形式如:classpath:cn/qing/java/bean.xml
加载类路径资源,classpath: 和 classpath:/ 是等价的,都是相对于类的根路径。资源文件可以在项目系统中,也可以在jar或zip的类包中包含,使用这种方式,都是可以正常访问。
file: 访问文件系统资源
使用形式如:file:d:/resource/test.xml
http:// 访问web服务器资源
使用形式:http://www.spring.org/test.xml 使用UrlResource类从web服务器加载资源
ftp:// 访问ftp服务器资源
使用形式: ftp://www.spring.org/test.xml
以上这几种资源前缀访问都支持通配符的形式进行访问,支持3中通配符:
? 匹配文件名中的一个字符
* 匹配文件名中的任意字符
** 匹配多层路径
示例:
classpath:/cn/qing/te?t.xml 用来匹配cn/qing/test.xml或cn/qing/teot.xml等文件
classpath:/cn/qing/*.xml 用来匹配cn/qing/下所有以xml后缀的资源文件
classpath:/cn/**/test.xml 用来匹配cn/目录及其子孙目录下的所有test.xml资源文件
如何使用前缀指定的资源地址来访问资源,Spring提供了一个标准实现类PathMatchingResourcePatternResolver用来访问资源。
实例如下:
package cn.qing.spring.resource;
import java.io.IOException;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
public class TestPatternResolver {
/**
* @param args
*/
public static void main(String[] args) {
//使用Spring提供的PathMatchingResourcePatternResolver实现类可以根据一个资源地址加载资源文件
ResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver();
try {
//得到匹配的所有资源
Resource[] resources = patternResolver.getResources("classpath:/*resource.*");
for(Resource rs : resources)
{
System.out.println("resource fileName:"+rs.getFilename());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
输出结果:
resource fileName:resource.properties
resource fileName:xmlresource.xml
根据结果可以看到,Spring可以正常获取这种通配符定义的资源。
ps:在使用PathMatchingResourcePatternResolver时Spring会用到LogFactory对象,所以我们需要引入commons-logging.jar包,程序才能正常运行。