# 【第四章】 資源 之 4.2 內置Resource實現 ——跟我學spring3
###
## 4.2? 內置Resource實現
### 4.2.1? ByteArrayResource
ByteArrayResource代表byte[]數組資源,對于“getInputStream”操作將返回一個ByteArrayInputStream。
首先讓我們看下使用ByteArrayResource如何處理byte數組資源:
```
package cn.javass.spring.chapter4;
import java.io.IOException;
import java.io.InputStream;
import org.junit.Test;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
public class ResourceTest {
@Test
public void testByteArrayResource() {
Resource resource = new ByteArrayResource("Hello World!".getBytes());
if(resource.exists()) {
dumpStream(resource);
}
}
}
```
是不是很簡單,讓我們看下“dumpStream”實現:
```
private 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) {
}
}
}
```
讓我們來仔細看一下代碼,dumpStream方法很抽象定義了訪問流的三部曲:打開資源、讀取資源、關閉資源,所以dunpStrean可以再進行抽象從而能在自己項目中使用;byteArrayResourceTest測試方法,也定義了基本步驟:定義資源、驗證資源存在、訪問資源。
ByteArrayResource可多次讀取數組資源,即isOpen ()永遠返回false。
### 1.2.2? InputStreamResource
InputStreamResource代表java.io.InputStream字節流,對于“getInputStream ”操作將直接返回該字節流,因此只能讀取一次該字節流,即“isOpen”永遠返回true。
讓我們看下測試代碼吧:
```
@Test
public void testInputStreamResource() {
ByteArrayInputStream bis = new ByteArrayInputStream("Hello World!".getBytes());
Resource resource = new InputStreamResource(bis);
if(resource.exists()) {
dumpStream(resource);
}
Assert.assertEquals(true, resource.isOpen());
}
```
測試代碼幾乎和ByteArrayResource測試完全一樣,注意“isOpen”此處用于返回true。
### 4.2.3? FileSystemResource
FileSystemResource代表java.io.File資源,對于“getInputStream ”操作將返回底層文件的字節流,“isOpen”將永遠返回false,從而表示可多次讀取底層文件的字節流。
讓我們看下測試代碼吧:
```
@Test
public void testFileResource() {
File file = new File("d:/test.txt");
Resource resource = new FileSystemResource(file);
if(resource.exists()) {
dumpStream(resource);
}
Assert.assertEquals(false, resource.isOpen());
}
```
注意由于“isOpen”將永遠返回false,所以可以多次調用dumpStream(resource)。
### 4.2.4? ClassPathResource
ClassPathResource代表classpath路徑的資源,將使用ClassLoader進行加載資源。classpath 資源存在于類路徑中的文件系統中或jar包里,且“isOpen”永遠返回false,表示可多次讀取資源。
ClassPathResource加載資源替代了Class類和ClassLoader類的“(?name)”和“(?name)”兩個加載類路徑資源方法,提供一致的訪問方式。
ClassPathResource提供了三個構造器:
**public ClassPathResource(String path)**:使用默認的ClassLoader加載“path”類路徑資源;
**public ClassPathResource(String path, ClassLoader classLoader):**使用指定的ClassLoader加載“path”類路徑資源;
比如當前類路徑是“cn.javass.spring.chapter4.ResourceTest”,而需要加載的資源路徑是“cn/javass/spring/chapter4/test1.properties”,則將加載的資源在“cn/javass/spring/chapter4/test1.properties”;
**public ClassPathResource(String path, Class<?> clazz):**使用指定的類加載“path”類路徑資源,將加載相對于當前類的路徑的資源;
比如當前類路徑是“cn.javass.spring.chapter4.ResourceTest”,而需要加載的資源路徑是“cn/javass/spring/chapter4/test1.properties”,則將加載的資源在“cn/javass/spring/chapter4/cn/javass/spring/chapter4/test1.properties”;
而如果需要 加載的資源路徑為“test1.properties”,將加載的資源為“cn/javass/spring/chapter4/test1.properties”。
讓我們直接看測試代碼吧:
1)使用默認的加載器加載資源,將加載當前ClassLoader類路徑上相對于根路徑的資源:
```
@Test
public void testClasspathResourceByDefaultClassLoader() throws IOException {
Resource resource = new ClassPathResource("cn/javass/spring/chapter4/test1.properties");
if(resource.exists()) {
dumpStream(resource);
}
System.out.println("path:" + resource.getFile().getAbsolutePath());
Assert.assertEquals(false, resource.isOpen());
}
```
2)使用指定的ClassLoader進行加載資源,將加載指定的ClassLoader類路徑上相對于根路徑的資源:
```
@Test
public void testClasspathResourceByClassLoader() throws IOException {
ClassLoader cl = this.getClass().getClassLoader();
Resource resource = new ClassPathResource("cn/javass/spring/chapter4/test1.properties" , cl);
if(resource.exists()) {
dumpStream(resource);
}
System.out.println("path:" + resource.getFile().getAbsolutePath());
Assert.assertEquals(false, resource.isOpen());
}
```
3)使用指定的類進行加載資源,將嘗試加載相對于當前類的路徑的資源:
```
@Test
public void testClasspathResourceByClass() throws IOException {
Class clazz = this.getClass();
Resource resource1 = new ClassPathResource("cn/javass/spring/chapter4/test1.properties" , clazz);
if(resource1.exists()) {
dumpStream(resource1);
}
System.out.println("path:" + resource1.getFile().getAbsolutePath());
Assert.assertEquals(false, resource1.isOpen());
Resource resource2 = new ClassPathResource("test1.properties" , this.getClass());
if(resource2.exists()) {
dumpStream(resource2);
}
System.out.println("path:" + resource2.getFile().getAbsolutePath());
Assert.assertEquals(false, resource2.isOpen());
}
```
“resource1”將加載cn/javass/spring/chapter4/cn/javass/spring/chapter4/test1.properties資源;“resource2”將加載“cn/javass/spring/chapter4/test1.properties”;
4)加載jar包里的資源,首先在當前類路徑下找不到,最后才到Jar包里找,而且在第一個Jar包里找到的將被返回:
```
@Test
public void classpathResourceTestFromJar() throws IOException {
Resource resource = new ClassPathResource("overview.html");
if(resource.exists()) {
dumpStream(resource);
}
System.out.println("path:" + resource.getURL().getPath());
Assert.assertEquals(false, resource.isOpen());
}
```
如果當前類路徑包含“overview.html”,在項目的“resources”目錄下,將加載該資源,否則將加載Jar包里的“overview.html”,而且不能使用“resource.getFile()”,應該使用“resource.getURL()”,因為資源不存在于文件系統而是存在于jar包里,URL類似于“file:/C:/.../***.jar!/overview.html”。
類路徑一般都是相對路徑,即相對于類路徑或相對于當前類的路徑,因此如果使用“/test1.properties”帶前綴“/”的路徑,將自動刪除“/”得到“test1.properties”。
### 4.2.5? UrlResource
UrlResource代表URL資源,用于簡化URL資源訪問。“isOpen”永遠返回false,表示可多次讀取資源。
UrlResource一般支持如下資源訪問:
**http:**通過標準的http協議訪問web資源,如new UrlResource(“http://地址”);
**ftp:**通過ftp協議訪問資源,如new UrlResource(“ftp://地址”);
**file:**通過file協議訪問本地文件系統資源,如new UrlResource(“file:d:/test.txt”);
具體使用方法在此就不演示了,可以參考cn.javass.spring.chapter4.ResourceTest中urlResourceTest測試方法。
### 4.2.6? ServletContextResource
ServletContextResource代表web應用資源,用于簡化servlet容器的ServletContext接口的getResource操作和getResourceAsStream操作;在此就不具體演示了。
### 4.2.7? VfsResource
VfsResource代表Jboss 虛擬文件系統資源。
Jboss VFS(Virtual File System)框架是一個文件系統資源訪問的抽象層,它能一致的訪問物理文件系統、jar資源、zip資源、war資源等,VFS能把這些資源一致的映射到一個目錄上,訪問它們就像訪問物理文件資源一樣,而其實這些資源不存在于物理文件系統。
在示例之前需要準備一些jar包,在此我們使用的是Jboss VFS3版本,可以下載最新的Jboss AS 6x,拷貝lib目錄下的“jboss-logging.jar”和“jboss-vfs.jar”兩個jar包拷貝到我們項目的lib目錄中并添加到“Java Build Path”中的“Libaries”中。
讓我們看下示例(cn.javass.spring.chapter4.ResourceTest):
```
@Test
public void testVfsResourceForRealFileSystem() throws IOException {
//1.創建一個虛擬的文件目錄
VirtualFile home = VFS.getChild("/home");
//2.將虛擬目錄映射到物理的目錄
VFS.mount(home, new RealFileSystem(new File("d:")));
//3.通過虛擬目錄獲取文件資源
VirtualFile testFile = home.getChild("test.txt");
//4.通過一致的接口訪問
Resource resource = new VfsResource(testFile);
if(resource.exists()) {
dumpStream(resource);
}
System.out.println("path:" + resource.getFile().getAbsolutePath());
Assert.assertEquals(false, resource.isOpen());
}
@Test
public void testVfsResourceForJar() throws IOException {
//1.首先獲取jar包路徑
File realFile = new File("lib/org.springframework.beans-3.0.5.RELEASE.jar");
//2.創建一個虛擬的文件目錄
VirtualFile home = VFS.getChild("/home2");
//3.將虛擬目錄映射到物理的目錄
VFS.mountZipExpanded(realFile, home,
TempFileProvider.create("tmp", Executors.newScheduledThreadPool(1)));
//4.通過虛擬目錄獲取文件資源
VirtualFile testFile = home.getChild("META-INF/spring.handlers");
Resource resource = new VfsResource(testFile);
if(resource.exists()) {
dumpStream(resource);
}
System.out.println("path:" + resource.getFile().getAbsolutePath());
Assert.assertEquals(false, resource.isOpen());
}
```
通過VFS,對于jar里的資源和物理文件系統訪問都具有一致性,此處只是簡單示例,如果需要請到Jboss官網深入學習。
原創內容 轉自請注明出處【[http://sishuok.com/forum/blogPost/list/0/2456.html](http://sishuok.com/forum/blogPost/list/0/2456.html#7104)】
- 跟我學 Spring3
- 【第二章】 IoC 之 2.1 IoC基礎 ——跟我學Spring3
- 【第二章】 IoC 之 2.2 IoC 容器基本原理 ——跟我學Spring3
- 【第二章】 IoC 之 2.3 IoC的配置使用——跟我學Spring3
- 【第三章】 DI 之 3.1 DI的配置使用 ——跟我學spring3
- 【第三章】 DI 之 3.2 循環依賴 ——跟我學spring3
- 【第三章】 DI 之 3.3 更多DI的知識 ——跟我學spring3
- 【第三章】 DI 之 3.4 Bean的作用域 ——跟我學spring3
- 【第四章】 資源 之 4.1 基礎知識 ——跟我學spring3
- 【第四章】 資源 之 4.2 內置Resource實現 ——跟我學spring3
- 【第四章】 資源 之 4.3 訪問Resource ——跟我學spring3
- 【第四章】 資源 之 4.4 Resource通配符路徑 ——跟我學spring3
- 【第五章】Spring表達式語言 之 5.1 概述 5.2 SpEL基礎 ——跟我學spring3
- 【第五章】Spring表達式語言 之 5.3 SpEL語法 ——跟我學spring3
- 【第五章】Spring表達式語言 之 5.4在Bean定義中使用EL—跟我學spring3
- 【第六章】 AOP 之 6.1 AOP基礎 ——跟我學spring3
- 【第六章】 AOP 之 6.2 AOP的HelloWorld ——跟我學spring3
- 【第六章】 AOP 之 6.3 基于Schema的AOP ——跟我學spring3
- 【第六章】 AOP 之 6.4 基于@AspectJ的AOP ——跟我學spring3
- 【第六章】 AOP 之 6.5 AspectJ切入點語法詳解 ——跟我學spring3
- 【第六章】 AOP 之 6.6 通知參數 ——跟我學spring3
- 【第六章】 AOP 之 6.7 通知順序 ——跟我學spring3
- 【第六章】 AOP 之 6.8 切面實例化模型 ——跟我學spring3
- 【第六章】 AOP 之 6.9 代理機制 ——跟我學spring3
- 【第七章】 對JDBC的支持 之 7.1 概述 ——跟我學spring3
- 【第七章】 對JDBC的支持 之 7.2 JDBC模板類 ——跟我學spring3
- 【第七章】 對JDBC的支持 之 7.3 關系數據庫操作對象化 ——跟我學spring3
- 【第七章】 對JDBC的支持 之 7.4 Spring提供的其它幫助 ——跟我學spring3【私塾在線原創】
- 【第七章】 對JDBC的支持 之 7.5 集成Spring JDBC及最佳實踐 ——跟我學spring3
- 【第八章】 對ORM的支持 之 8.1 概述 ——跟我學spring3
- 【第八章】 對ORM的支持 之 8.2 集成Hibernate3 ——跟我學spring3
- 【第八章】 對ORM的支持 之 8.3 集成iBATIS ——跟我學spring3
- 【第八章】 對ORM的支持 之 8.4 集成JPA ——跟我學spring3
- 【第九章】 Spring的事務 之 9.1 數據庫事務概述 ——跟我學spring3
- 【第九章】 Spring的事務 之 9.2 事務管理器 ——跟我學spring3
- 【第九章】 Spring的事務 之 9.3 編程式事務 ——跟我學spring3
- 【第九章】 Spring的事務 之 9.4 聲明式事務 ——跟我學spring3
- 【第十章】集成其它Web框架 之 10.1 概述 ——跟我學spring3
- 【第十章】集成其它Web框架 之 10.2 集成Struts1.x ——跟我學spring3
- 【第十章】集成其它Web框架 之 10.3 集成Struts2.x ——跟我學spring3
- 【第十章】集成其它Web框架 之 10.4 集成JSF ——跟我學spring3
- 【第十一章】 SSH集成開發積分商城 之 11.1 概述 ——跟我學spring3
- 【第十一章】 SSH集成開發積分商城 之 11.2 實現通用層 ——跟我學spring3
- 【第十一章】 SSH集成開發積分商城 之 11.3 實現積分商城層 ——跟我學spring3
- 【第十二章】零配置 之 12.1 概述 ——跟我學spring3
- 【第十二章】零配置 之 12.2 注解實現Bean依賴注入 ——跟我學spring3
- 【第十二章】零配置 之 12.3 注解實現Bean定義 ——跟我學spring3
- 【第十二章】零配置 之 12.4 基于Java類定義Bean配置元數據 ——跟我學spring3
- 【第十二章】零配置 之 12.5 綜合示例-積分商城 ——跟我學spring3
- 【第十三章】 測試 之 13.1 概述 13.2 單元測試 ——跟我學spring3
- 【第十三章】 測試 之 13.3 集成測試 ——跟我學spring3
- 跟我學 Spring MVC
- SpringMVC + spring3.1.1 + hibernate4.1.0 集成及常見問題總結
- Spring Web MVC中的頁面緩存支持 ——跟我學SpringMVC系列
- Spring3 Web MVC下的數據類型轉換(第一篇)——《跟我學Spring3 Web MVC》搶先看
- Spring3 Web MVC下的數據格式化(第二篇)——《跟我學Spring3 Web MVC》搶先看
- 第一章 Web MVC簡介 —— 跟開濤學SpringMVC
- 第二章 Spring MVC入門 —— 跟開濤學SpringMVC
- 第三章 DispatcherServlet詳解 ——跟開濤學SpringMVC
- 第四章 Controller接口控制器詳解(1)——跟著開濤學SpringMVC
- 第四章 Controller接口控制器詳解(2)——跟著開濤學SpringMVC
- 第四章 Controller接口控制器詳解(3)——跟著開濤學SpringMVC
- 第四章 Controller接口控制器詳解 (4)——跟著開濤學SpringMVC
- 第四章 Controller接口控制器詳解(5)——跟著開濤學SpringMVC
- 跟著開濤學SpringMVC 第一章源代碼下載
- 第二章 Spring MVC入門 源代碼下載
- 第四章 Controller接口控制器詳解 源代碼下載
- 第四章 Controller接口控制器詳解(6)——跟著開濤學SpringMVC
- 第四章 Controller接口控制器詳解(7 完)——跟著開濤學SpringMVC
- 第五章 處理器攔截器詳解——跟著開濤學SpringMVC
- 源代碼下載 第五章 處理器攔截器詳解——跟著開濤學SpringMVC
- 注解式控制器運行流程及處理器定義 第六章 注解式控制器詳解——跟著開濤學SpringMVC
- 源代碼下載 第六章 注解式控制器詳解
- SpringMVC3強大的請求映射規則詳解 第六章 注解式控制器詳解——跟著開濤學SpringMVC
- Spring MVC 3.1新特性 生產者、消費者請求限定 —— 第六章 注解式控制器詳解——跟著開濤學SpringMVC
- SpringMVC強大的數據綁定(1)——第六章 注解式控制器詳解——跟著開濤學SpringMVC
- SpringMVC強大的數據綁定(2)——第六章 注解式控制器詳解——跟著開濤學SpringMVC
- SpringMVC數據類型轉換——第七章 注解式控制器的數據驗證、類型轉換及格式化——跟著開濤學SpringMVC
- SpringMVC數據格式化——第七章 注解式控制器的數據驗證、類型轉換及格式化——跟著開濤學SpringMVC
- SpringMVC數據驗證——第七章 注解式控制器的數據驗證、類型轉換及格式化——跟著開濤學SpringMVC