Spring3外部资源访问之Resource接口

[size=medium][b]概述[/b]
在日常程序开发中,处理外部资源是很繁琐的事情,我们可能需要处理URL资源、File资源资源、ClassPath相关资源、服务器相关资源(JBoss AS 5.x上的VFS资源)等等很多资源。因此处理这些资源需要使用不同的接口,这就增加了我们系统的复杂性;而且处理这些资源步骤都是类似的(打开资源、读取资源、关闭资源),因此如果能抽象出一个统一的接口来对这些底层资源进行统一访问,是不是很方便,而且使我们系统更加简洁,都是对不同的底层资源使用同一个接口进行访问。
Spring提供一个Resource接口来统一这些底层资源一致的访问,而且提供了一些便利的接口,从而能提供我们的生产力。

[b]Resource接口[/b]
Spring的Resource接口代表底层外部资源,提供了对底层外部资源的一致性访问接口。

[color=blue]InputStreamSource接口解析:[/color]
● getInputStream:每次调用都将返回一个新鲜的资源对应的java.io.InputStream字节流,调用者在使用完毕后必须关闭该资源。[/size]

public interface InputStreamSource {
InputStream getInputStream() throws IOException;
}

[size=medium][color=blue]Resource接口继承InputStreamSource接口,并提供一些便利方法:[/color]
● [b]exists[/b]:返回当前Resource代表的底层资源是否存在
● [b]isReadable[/b]:返回当前Resource代表的底层资源是否可读
● [b]isOpen[/b]:返回当前Resource代表的底层资源是否已经打开,如果返回true,则只能被读取一次然后关闭以避免内存泄漏;常见的Resource实现一般返回false
● [b]getURL[/b]:如果当前Resource代表的底层资源能由java.util.URL代表,则返回该URL,否则抛出IO异常
● [b]getURI[/b]:如果当前Resource代表的底层资源能由java.util.URI代表,则返回该URI,否则抛出IO异常
● [b]getFile[/b]:如果当前Resource代表的底层资源能由java.io.File代表,则返回该File,否则抛出IO异常
● [b]contentLength[/b]:返回当前Resource代表的底层文件资源的长度,一般是值代表的文件资源的长度。
● [b]lastModified[/b]:返回当前Resource代表的底层资源的最后修改时间。
● [b]createRelative[/b]:用于创建相对于当前Resource代表的底层资源的资源,比如当前Resource代表文件资源“d:/test/”则createRelative(“test.txt”)将返回表文件资源“d:/test/test.txt”Resource资源。
● [b]getFilename[/b]:返回当前Resource代表的底层文件资源的文件路径,比如File资源“file://d:/test.txt”将返回“d:/test.txt”,而URL资源http://www.javass.cn将返回“”,因为只返回文件路径。
● [b]getDescription[/b]:返回当前Resource代表的底层资源的描述符,通常就是资源的全路径(实际文件名或实际URL地址)。[/size]

public interface Resource extends InputStreamSource {
boolean exists();
boolean isReadable();
boolean isOpen();
URL getURL() throws IOException;
URI getURI() throws IOException;
File getFile() throws IOException;
long contentLength() throws IOException;
long lastModified() throws IOException;
Resource createRelative(String relativePath) throws IOException;
String getFilename();
String getDescription();
}


[size=medium]Resource接口提供了足够的抽象,足够满足我们日常使用。而且提供了很多内置Resource实现:ByteArrayResource、InputStreamResource 、FileSystemResource 、UrlResource 、ClassPathResource、ServletContextResource、VfsResource等

[b][color=red]ByteArrayResource[/color][/b]可多次读取数组资源,即isOpen()永远返回false[/size]

public static void Test_ByteArrayResource() {
Resource resource = new ByteArrayResource("Hello!Spring!你好!".getBytes());
if (resource.exists()) {
dumpStream(resource);
}
}

private static void dumpStream(Resource resource) {
InputStream is = null;
try {
//1.获取文件资源
is = resource.getInputStream();
//2.读取资源
byte[] descBytes = new byte[is.available()];
is.read(descBytes);
System.out.println(new String(descBytes));
} catch (IOException e) {
e.printStackTrace();
}
finally {
try {
//3.关闭资源
is.close();
} catch (IOException e) {
}
}
}


[size=medium][b][color=red]InputStreamResource[/color][/b]代表java.io.InputStream字节流,对于getInputStream操作将直接返回该字节流,因此只能读取一次该字节流,即isOpen永远返回true[/size]

public static void Test_InputStreamResource() {
ByteArrayInputStream bis = new ByteArrayInputStream(
"Hello Spring!".getBytes());
Resource resource = new InputStreamResource(bis);
if (resource.exists()) {
dumpStream(resource);
}
Assert.isTrue(resource.isOpen());
}


[size=medium][b][color=red]FileSystemResource[/color][/b]代表java.io.File资源,对于getInputStream操作将返回底层文件的字节流,isOpen将永远返回false,从而表示可多次读取底层文件的字节流。[/size]

public static void Test_FileSystemResource() {
File file = new File("d:/test.txt");
Resource resource = new FileSystemResource(file);
if (resource.exists()) {
dumpStream(resource);
}
Assert.isTrue(!resource.isOpen());
}


[size=medium][b][color=red]ClassPathResource[/color][/b]代表classpath路径的资源,将使用ClassLoader进行加载资源。classpath资源存在于类路径中的文件系统中或jar包里,且isOpen永远返回false,表示可多次读取资源。
ClassPathResource加载资源替代了Class类和ClassLoader类的getResource(String name)和getResourceAsStream(String name)两个加载类路径资源方法,提供一致的访问方式。
[color=blue]ClassPathResource提供了三个构造器[/color]:
● public ClassPathResource(String path):使用默认的ClassLoader加载“path”类路径资源;
● public ClassPathResource(String path, ClassLoader classLoader):使用指定的ClassLoader加载“path”类路径资源;
● public ClassPathResource(String path, Class<?> clazz):使用指定的类加载“path”类路径资源,将加载相对于当前类的路径的资源;
[/size]

public static void Test_ClassPathResource() throws IOException {
Resource resource = new ClassPathResource("demo.properties");
if (resource.exists()) {
dumpStream(resource);
}
System.out.println("path:" + resource.getFile().getAbsolutePath());
Assert.isTrue(!resource.isOpen());
}


[size=medium][b][color=red]UrlResource[/color][/b]代表URL资源,用于简化URL资源访问。isOpen永远返回false,表示可多次读取资源。
UrlResource一般支持如下资源访问:
● [b]http[/b]:通过标准的http协议访问web资源,如new UrlResource(“http://地址”);
● [b]ftp[/b]:通过ftp协议访问资源,如new UrlResource(“ftp://地址”);
● [b]file[/b]:通过file协议访问本地文件系统资源,如new UrlResource(“file:d:/test.txt”)

[b][color=red]ServletContextResource[/color][/b]代表web应用资源,用于简化servlet容器的ServletContext接口的getResource操作和getResourceAsStream操作。

[b][color=red]VfsResource[/color][/b]代表Jboss 虚拟文件系统资源。
Jboss VFS(Virtual File System)框架是一个文件系统资源访问的抽象层,它能一致的访问物理文件系统、jar资源、zip资源、war资源等,VFS能把这些资源一致的映射到一个目录上,访问它们就像访问物理文件资源一样,而其实这些资源不存在于物理文件系统。

具体用法可以参考博客:[url]http://jinnianshilongnian.iteye.com/blog/1416320[/url][/size]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值