Sprint資源訪問
目錄
一、資源抽象介面
1、傳統java中的資源載入
通過ClassLoader類載入器進行的。程式碼如下:
Thread.currentThread().getContextClassLoader().getResource("com/demo/SimpleJava.class");
SimpleJava.class.getClassLoader().getResource("com/demo/SimpleJava.class");
ClassLoader.getSystemResource("com/demo/SimpleJava.class");
SimpleJava.class.getResource("SimpleJava.class");
每個類載入器載入資源時,都有自己固定的位置,也就是例項化類載入器時傳遞的url,相當於類載入器載入的資源的倉庫,也只會在自己的的倉庫中尋找資源,而classPath下的資源,都是AppClassLoader類進行載入。
對於通過SimpleJava.class.getResource進行的資源載入,我們可以通過分析原始碼:
//這是class類中進行資源載入的方法
public java.net.URL getResource(String name) {
name = resolveName(name); //通過解析資源名稱,如果是以/開頭,會在classpath下找尋,name必須為包含全限定名稱的路徑。
//上面的例子中SimpleJava.class.getResource("SimpleJava.class")的路徑可以換成:/com/demo/SimpleJava.class,如果不是以/開頭,則會在相對於SimpleJava.class的目錄下找尋。
ClassLoader cl = getClassLoader0();
if (cl==null) {
return ClassLoader.getSystemResource(name);
}
return cl.getResource(name);
}
2、Spring中的Resource介面
傳統的Java資原始檔的訪問通過JDK中的File、URL類難以滿足各種不同需求的資源載入,這裡有Spring中設計的org.springframework.core.io.Resource介面提供更加強大的訪問底層資源的能力。
下面是Resource介面的主要方法:
boolean exists():資源是否存在;
boolean isOpen():資源是否開啟;
URL getURL() throws IOException:如果底層資源可以表示成URL,該方法返回對應的URL物件;
File getFile() throws IOException:如果底層資源對應一個檔案,該方法返回對應的File物件;
InputStream getInputStream() throws IOException:返回資源對應的輸入流;
Resource具體實現類如下:
ByteArrayResource:二進位制陣列表示的資源;
ClassPathResource:類路徑下的資源,資源以相對於類路徑的方式表示;
FileSystemResource:檔案系統資源,資源以檔案系統路徑的方式表示;
InputStreamResource:以輸入流返回表示的資源;
ServletContextResource:為訪問訪問Web容器上下文中的資源而設計的類,負責以相對於Web應用程式根目錄的路徑載入資源,它支援以流和URL的方式訪問,在WAR解包的情況下,也可以通過File的方式訪問,還可以直接從JAR包中訪問資源;
URLResource:Url封裝了java.net.URL,它使使用者能夠訪問任何可以通過URL表示的資源,如檔案系統的資源、HTTP資源、FTP資源;
PathResource:Spring4.0提供的讀取資原始檔的新類。Path封裝了java.net.URL、java.nio.file.Path、檔案系統資源,它使使用者能夠訪問任何可以同喲URL、Path、系統檔案路徑表示的資源,如檔案系統的資源、Http資源、FTP資源;
如下分別通過FileSystemResource和ClassPathResource訪問同一個檔案資源:
/**
* Sping獲取資源的介面
* 繼承的介面有:WritableResource
* 實現類有:
* PathResource
* ClassPathResource
* FileSystemResource等
*/
@Test
public void test_resource() throws IOException {
//使用系統檔案路徑方式載入資源
//WritableResource介面繼承介面Resource,新增了 isWritable/getOutputStream 方法
String filePath = "/Users/admin/spr-mybatis-web/src/main/resources/note/note.txt";
WritableResource res1 = new PathResource(filePath);
//使用類路徑方式載入資源
Resource res2 = new ClassPathResource("note/note.txt");
//使用WritableResource介面讀取資原始檔
OutputStream stream1 = res1.getOutputStream();
stream1.write("這個是測試".getBytes());
stream1.close();
//使用Resource介面讀取資源
InputStream ins1 = res1.getInputStream();
InputStream ins2 = res2.getInputStream();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int i;
while ((i = ins1.read()) != -1) {
bos.write(i);
}
System.out.println(bos.toString());
System.out.println(res1.getFilename());
System.out.println(res2.getFilename());
}
獲取到資源後,可以通過getFileName()獲取方法名,通過getFile()獲取資源對應的File檔案,通過getInputStream()直接獲取檔案的輸入流,還可通過createRelative(String relativePath)在資源相對地址上建立新的檔案。
如下是在Web應用中通過ServletContextResource以相對於Web應用根目錄的方式訪問檔案資源:
Resource res3 = new ServletContextResource(application,"/WEB-INF/classes/conf/file1.txt");
可以通過EncodedResource對資源進行編碼,保證資源內容操作的正確性,如下:
Resource res = new ClassPathResource("conf/file1.txt");
EncodedResource encRes = new EncodedResource(res,"UTF-8");
String content = FileCopyUtils.copyToString(encRes.getReader());
System.out.println(content);
二、資源載入
為了訪問不同型別的資源,必須使用相應的Resorce實現類,這是比較麻煩的,spring提供了一個強大的載入資源的機制,能夠自動識別不同的資源型別。
1、資源地址表示式
地址字首 | 示例 | 對應的資源型別 |
classpath: | classpath:com/bean/bean.xml | 表示從類路徑載入資源,classpath:和classpath:/是等價的,都是相對於類的根路徑。資原始檔可以在標準的檔案系統中,也可以在jar或zip的類包中 |
file: | file:/com/bean/bean.xml | 使用UrlResource從檔案系統目錄中裝載資源,可採用絕對或相對路徑 |
http:// | http://www.csdn.bean.xml | 使用UrlResource從Web伺服器中裝載資源 |
ftp:// | ftp://www.csdn.bean.xml | 使用UrlResource從FTP伺服器中裝載資源 |
沒有字首 | com/bean/bean.xml | 根據ApplicationContext的具體實現類採用對應型別的Resource |
其中,classpath:和classpath*:的區別在於classpath*:會掃描所有類路徑下出現的資源,而classpath只會在第一個載入的包下查詢,即就是隻載入一個資原始檔。
匹配風格資源地址支援3種:
?:匹配檔案中的一個字元
* :匹配檔案中的任意字元
** :匹配多層路徑
如:file:/com/bean/bea?.xml
2、資源載入器
Spring定義了一套資源載入的介面,並提供了實現類。
2-1、Resource介面
位於包 org.springframework.core.io 下,提供了一些基本方法,如 exists()/getResource()等方法
2-2、ResourcePatternResolver介面
位於包 org.springframework.core.io.support 下,繼承了介面ResourceLoader,增加了Resource[] getResources(String var1)方法,可以看出相對與ResourceLoader介面而言增加了批量載入檔案方法。新增了資源匹配模式表示式,但不支援匹配風格地址載入資源。
2-3、PathMatchingResourcePatternResolver類
位於包 org.springframework.core.io.support 下,實現了介面 ResourcePatternResolver。新增了支援匹配風格地址載入資源。
具體程式碼如下:
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
Resource[] resources = resourcePatternResolver.getResources("classpath*:note/not?.txt");
for(Resource resource:resources){
System.out.println(resource.getFilename());
}
三、總結
1、傳統java中的資源載入,是通過類載入器進行獲取資源;
2、Spring獲取資源提供了Resource介面,該介面提供了獲取資源的及其相關方法,並針對不同資源獲取方式提供了不同的實現類;
3、為了訪問不同型別的資源,必須使用相應的Resorce實現類,這是比較麻煩的,spring提供了一個強大的載入資源的機制,能夠自動識別不同的資源型別。Spring為其提供了資源表示式和資源載入器介面和實現類。
相關文章
- SpringBoot靜態資源訪問Spring Boot
- Android資源訪問機制Android
- springboot+themeleaf+bootstrap訪問靜態資源/無法訪問靜態資源/圖片Spring Boot
- 加密訪問資源方法總結加密
- Springboot中如何訪問靜態資源Spring Boot
- Nginx解決前端訪問資源跨域問題Nginx前端跨域
- [開源] .Net ORM 訪問 Firebird 資料庫ORM資料庫
- CDN及CDN資源訪問流程簡介
- SpringMVC下關於靜態資源訪問SpringMVC
- springboot新增靜態資源無法訪問Spring Boot
- Oracle RAC Cache Fusion 系列十三:PCM資源訪問Oracle
- webpack簡單搭建localhost訪問靜態資源Weblocalhost
- SpringBoot資料訪問之Druid資料來源的使用Spring BootUI
- SpringBoot之yaml語法及靜態資源訪問Spring BootYAML
- 從零搭建一個IdentityServer——資源與訪問控制IDEServer
- 關於 RemoteViews 跨程式資源訪問的勘誤REMView
- 在kubernetes裡使用AppArmor限制容器對資源的訪問APP
- [開源] .Net 使用 ORM 訪問 華為GaussDB資料庫ORM資料庫
- 跨源通訊、跨域訪問跨域
- 比nestjs更優雅的ioc:跨模組訪問資源JS
- Spring資料訪問Spring
- Laravel 在 Docker 環境下訪問 storage 靜態資源 404 問題解決LaravelDocker
- cdn.jsdelivr.net 掛了?前端靜態資源訪問出錯JSVR前端
- 資料訪問 - EntityFramework整合Framework
- JDBC資料庫訪問JDBC資料庫
- Identity Server 4資源擁有者密碼認證控制訪問APIIDEServer密碼API
- [測試]Sprint Bootboot
- 【原始碼分析】 - SprignBoot是如何訪問工程目錄下的靜態資源?原始碼boot
- 讓 TiDB 訪問多種資料來源 | TiDB Hackathon 優秀專案分享TiDB
- 【SpringBoot實戰】資料訪問Spring Boot
- SpringMVC中已經配置了靜態資源,依然無法訪問,css可以訪問成功,但圖片就是載入不出來。SpringMVCCSS
- 阿里雲開源映象站支援IPv6訪問阿里
- 模擬衝刺sprint
- Scrum 之 Sprint Backlog 概述Scrum
- Oracle資料庫限制訪問IPOracle資料庫
- SQL Server 資料訪問策略:CLRMESQLServer
- ABP 資料訪問 - IRepository 倉儲
- 外網訪問MySQL資料庫MySql資料庫