Spring3.0第四講:資源訪問(wèn)利器-Resource-創(chuàng)新互聯(lián)

JDK提供的訪問(wèn)資源的類(lèi)(如java.net.URL、File等)并不能很好的滿足各種底層資源的訪問(wèn),比如缺少?gòu)念?lèi)路徑以及web容器上下文獲取資源的操作類(lèi),因此,Spring設(shè)計(jì)了一個(gè)Resource接口,他提供了更強(qiáng)訪問(wèn)底層資源的能力,先來(lái)看看Resource接口的主要方法:

10年積累的網(wǎng)站制作、成都網(wǎng)站制作經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問(wèn)題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站設(shè)計(jì)后付款的網(wǎng)站建設(shè)流程,更有夏邑免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
  • exists():用于判斷對(duì)應(yīng)的資源是否真的存在。

  • isReadable():用于判斷對(duì)應(yīng)資源的內(nèi)容是否可讀。需要注意的是當(dāng)其結(jié)果為true的時(shí)候,其內(nèi)容未必真的可讀,但如果返回false,則其內(nèi)容必定不可讀。

  • isOpen():用于判斷當(dāng)前資源是否代表一個(gè)已打開(kāi)的輸入流,如果結(jié)果為true,則表示當(dāng)前資源的輸入流不可多次讀取,而且在讀取以后需要對(duì)它進(jìn)行關(guān)閉,以防止內(nèi)存泄露。該方法主要針對(duì)于InputStreamResource,實(shí)現(xiàn)類(lèi)中只有它的返回結(jié)果為true,其他都為false。

  • getURL():返回當(dāng)前資源對(duì)應(yīng)的URL。如果當(dāng)前資源不能解析為一個(gè)URL則會(huì)拋出異常。如ByteArrayResource就不能解析為一個(gè)URL。

  • getFile():返回當(dāng)前資源對(duì)應(yīng)的File。如果當(dāng)前資源不能以絕對(duì)路徑解析為一個(gè)File則會(huì)拋出異常。如ByteArrayResource就不能解析為一個(gè)File。

  • getInputStream():獲取當(dāng)前資源代表的輸入流。除了InputStreamResource以外,其它Resource實(shí)現(xiàn)類(lèi)每次調(diào)用getInputStream()方法都將返回一個(gè)全新的InputStream。

 Resource在Spring中占有重要作用,Spring用它來(lái)讀取配置文件、國(guó)際化屬性文件資源等下面來(lái)看一下Resource實(shí)現(xiàn)方法:

 Spring3.0第四講:資源訪問(wèn)利器-Resource

  • ByteArrayResource:二進(jìn)制數(shù)組表示的資源,二進(jìn)制數(shù)組源可以在內(nèi)存中通過(guò)程序構(gòu)造。

  • ClassPathResource:類(lèi)路徑下的資源,資源以相對(duì)于類(lèi)路徑的方式表示,如:new ClassPathResource("com/baobaotao/beanfactory/bean.xml")。

  • FileSystemResource:文件系統(tǒng)資源,資源以文件系統(tǒng)路徑的方式表示,如:new FileSystemResource("c:\\beans.xml")。

  • InputSteamResource:以輸入流返回表示的資源。

  • ServletContextResource:為訪問(wèn)Web容器上下文中的資源而設(shè)計(jì)的類(lèi),負(fù)責(zé)從Web應(yīng)用根目錄中加載資源,它支持以流和Url的方式訪問(wèn),在WAR解包的情況下,也可以通過(guò)File的方式訪問(wèn),該類(lèi)還可以直接從JAR包中訪問(wèn)資源。

  • UrlResource:Url封裝了java.net.URL,它使用戶能夠訪問(wèn)任何可以通過(guò)URL表示的資源,如文件系統(tǒng)的資源、HTTP資源、FTP資源等。

    有了這個(gè)抽象的資源類(lèi)后,我們就可以將Spring的配置信息放置在任何地方(如數(shù)據(jù)庫(kù)、LDAP中),只要最終可以通過(guò)Resource接口返回配置信息就可以了。

注意:Spring的Resource可以脫離Spring框架下單獨(dú)使用。

下面我們來(lái)看看Resource能給我們帶來(lái)什么?

訪問(wèn)文件資源

   現(xiàn)在我們假設(shè)Web項(xiàng)目類(lèi)路徑下有一個(gè)文件,那么我們應(yīng)該怎么去讀取呢?

①FileSystemResource通過(guò)系統(tǒng)的絕對(duì)路徑去讀取。

②ClassPathResource以類(lèi)路徑方式進(jìn)行訪問(wèn)。

③ServletContextResource以相對(duì)Web應(yīng)用根目錄的方式讀取。

相比較JDK提供的訪問(wèn)資源的方法,Resource可以讓我們根據(jù)需要進(jìn)行更多的選擇,下面我們來(lái)看一下2種方法實(shí)現(xiàn)的代碼(項(xiàng)目名稱(chēng)為Spring在其src下有個(gè)conf,里面有個(gè)test.txt的文件):

package test.com.gloryscience.service;

import java.io.IOException;
import java.io.InputStream;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;

public class ResourceTest {
	public static void main(String[] args) {
		try {
		String filepath="F:/guoxiangworkspace/Spring/WebContent/WEB-INF/classes/conf/test.txt";
		//以系統(tǒng)文件路徑的方式加載文件
		Resource fileresource=new FileSystemResource(filepath);
		//以class類(lèi)路徑加載文件
		Resource classsource=new ClassPathResource("/conf/test.txt");
		InputStream is2=classsource.getInputStream();
		InputStream is1=fileresource.getInputStream();
		System.out.println("通過(guò)FileSystemResource:"+fileresource.getFilename());
		System.out.println("通過(guò)ClassPathResource:"+classsource.getFilename());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

   在獲取資源后,您就可以通過(guò) Resource 接口定義的多個(gè)方法訪問(wèn)文件的數(shù)據(jù)和其它的信息:如您可以通過(guò) getFileName() 獲取文件名,通過(guò) getFile() 獲取資源對(duì)應(yīng)的 File 對(duì)象,通過(guò) getInputStream() 直接獲取文件的輸入流。此外,您還可以通過(guò) createRelative(String relativePath) 在資源相對(duì)地址上創(chuàng)建新的資源。

在 Web 應(yīng)用中,您還可以通過(guò) ServletContextResource 以相對(duì)于 Web 應(yīng)用根目錄的方式訪問(wèn)文件資源,如下所示:

 <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> 
 <jsp:directive.page import="
    org.springframework.web.context.support.ServletContextResource"/> 
 <jsp:directive.page import="org.springframework.core.io.Resource"/> 
 <% 
    // ① 注意文件資源地址以相對(duì)于 Web 應(yīng)用根路徑的方式表示
    Resource res3 = new ServletContextResource(application, 
        "/WEB-INF/classes/conf/file1.txt"); 
    out.print(res3.getFilename()); 
 %>

對(duì)于位于遠(yuǎn)程服務(wù)器(Web 服務(wù)器或 FTP 服務(wù)器)的文件資源,您則可以方便地通過(guò) UrlResource 進(jìn)行訪問(wèn)。

為了方便訪問(wèn)不同類(lèi)型的資源,您必須使用相應(yīng)的 Resource 實(shí)現(xiàn)類(lèi),是否可以在不顯式使用 Resource 實(shí)現(xiàn)類(lèi)的情況下,僅根據(jù)帶特殊前綴的資源地址直接加載文件資源呢? Spring 提供了一個(gè) ResourceUtils 工具類(lèi),它支持“classpath:”和“file:”的地址前綴,它能夠從指定的地址加載文件資源,請(qǐng)看下面的例子:

 import org.springframework.util.ResourceUtils; 
 public class ResourceUtilsExample { 
    public static void main(String[] args) throws Throwable{ 
        File clsFile = ResourceUtils.getFile("classpath:conf/file1.txt"); 
        System.out.println(clsFile.isFile()); 

        String httpFilePath = "file:D:/masterSpring/chapter23/src/conf/file1.txt"; 
        File httpFile = ResourceUtils.getFile(httpFilePath); 
        System.out.println(httpFile.isFile());        
    } 
 }

本地化文件資源

本地化文件資源是一組通過(guò)本地化標(biāo)識(shí)名進(jìn)行特殊命名的文件,Spring 提供的 LocalizedResourceHelper 允許通過(guò)文件資源基名和本地化實(shí)體獲取匹配的本地化文件資源并以 Resource 對(duì)象返回。假設(shè)在類(lèi)路徑的 i18n 目錄下,擁有一組基名為 message 的本地化文件資源,我們通過(guò)以下實(shí)例演示獲取對(duì)應(yīng)中國(guó)大陸和美國(guó)的本地化文件資源:
import java.util.Locale; 
 import org.springframework.core.io.Resource; 
 import org.springframework.core.io.support.LocalizedResourceHelper; 
 public class LocaleResourceTest { 
    public static void main(String[] args) { 
        LocalizedResourceHelper lrHalper = new LocalizedResourceHelper(); 
        // ① 獲取對(duì)應(yīng)美國(guó)的本地化文件資源
        Resource msg_us = lrHalper.findLocalizedResource("i18n/message", ".properties", 
        Locale.US); 
        // ② 獲取對(duì)應(yīng)中國(guó)大陸的本地化文件資源
        Resource msg_cn = lrHalper.findLocalizedResource("i18n/message", ".properties", 
        Locale.CHINA); 
        System.out.println("fileName(us):"+msg_us.getFilename()); 
        System.out.println("fileName(cn):"+msg_cn.getFilename()); 
    } 
 }

文件操作

在使用各種 Resource 接口的實(shí)現(xiàn)類(lèi)加載文件資源后,經(jīng)常需要對(duì)文件資源進(jìn)行讀取、拷貝、轉(zhuǎn)存等不同類(lèi)型的操作。您可以通過(guò) Resource 接口所提供了方法完成這些功能,不過(guò)在大多數(shù)情況下,通過(guò) Spring 為 Resource 所配備的工具類(lèi)完成文件資源的操作將更加方便。

 import java.io.ByteArrayOutputStream; 
 import java.io.File; 
 import java.io.FileReader; 
 import java.io.OutputStream; 
 import org.springframework.core.io.ClassPathResource; 
 import org.springframework.core.io.Resource; 
 import org.springframework.util.FileCopyUtils; 
 public class FileCopyUtilsExample { 
    public static void main(String[] args) throws Throwable { 
        Resource res = new ClassPathResource("conf/file1.txt"); 
        // ① 將文件內(nèi)容拷貝到一個(gè) byte[] 中
        byte[] fileData = FileCopyUtils.copyToByteArray(res.getFile()); 
        // ② 將文件內(nèi)容拷貝到一個(gè) String 中
        String fileStr = FileCopyUtils.copyToString(new FileReader(res.getFile())); 
        // ③ 將文件內(nèi)容拷貝到另一個(gè)目標(biāo)文件
        FileCopyUtils.copy(res.getFile(), 
        new File(res.getFile().getParent()+ "/file2.txt")); 

        // ④ 將文件內(nèi)容拷貝到一個(gè)輸出流中
        OutputStream os = new ByteArrayOutputStream(); 
        FileCopyUtils.copy(res.getInputStream(), os); 
    } 
 }

往往我們都通過(guò)直接操作 InputStream 讀取文件的內(nèi)容,但是流操作的代碼是比較底層的,代碼的面向?qū)ο笮圆⒉粡?qiáng)。通過(guò) FileCopyUtils 讀取和拷貝文件內(nèi)容易于操作且相當(dāng)直觀。如在 ① 處,我們通過(guò) FileCopyUtils 的 copyToByteArray(File in) 方法就可以直接將文件內(nèi)容讀到一個(gè) byte[] 中;另一個(gè)可用的方法是 copyToByteArray(InputStream in),它將輸入流讀取到一個(gè) byte[] 中。

如果是文本文件,您可能希望將文件內(nèi)容讀取到 String 中,此時(shí)您可以使用 copyToString(Reader in) 方法,如 ② 所示。使用 FileReader 對(duì) File 進(jìn)行封裝,或使用 InputStreamReader 對(duì) InputStream 進(jìn)行封裝就可以了。

FileCopyUtils 還提供了多個(gè)將文件內(nèi)容拷貝到各種目標(biāo)對(duì)象中的方法,這些方法包括:

                         方法                                                                  說(shuō)明

static void copy(byte[] in, File out)                              將 byte[] 拷貝到一個(gè)文件中  

static void copy(byte[] in, OutputStream out)             將 byte[] 拷貝到一個(gè)輸出流中  

static int copy(File in, File out)                                     將文件拷貝到另一個(gè)文件中  

static int copy(InputStream in, OutputStream out)    將輸入流拷貝到輸出流中  

static int copy(Reader in, Writer out)                          將 Reader 讀取的內(nèi)容拷貝到 Writer 指向目標(biāo)輸出中  

static void copy(String in, Writer out)                         將字符串拷貝到一個(gè) Writer 指向的目標(biāo)中  

在實(shí)例中,我們雖然使用 Resource 加載文件資源,但 FileCopyUtils 本身和 Resource 沒(méi)有任何關(guān)系,您完全可以在基于 JDK I/O API 的程序中使用這個(gè)工具類(lèi)。

屬性資源加載

我們知道可以通過(guò) java.util.Properties 的 load(InputStream inStream) 方法從一個(gè)輸入流中加載屬性資源。Spring 提供的 PropertiesLoaderUtils 允許您直接通過(guò)基于類(lèi)路徑的文件地址加載屬性資源,請(qǐng)看下面的例子:

 import java.util.Properties; 
 import org.springframework.core.io.support.PropertiesLoaderUtils; 
 public class PropertiesLoaderUtilsExample { 
    public static void main(String[] args) throws Throwable {    
        // ① jdbc.properties 是位于類(lèi)路徑下的文件
        Properties props = PropertiesLoaderUtils.loadAllProperties("jdbc.properties"); 
        System.out.println(props.getProperty("jdbc.driverClassName")); 
    } 
 }

一般情況下,應(yīng)用程序的屬性文件都放置在類(lèi)路徑下,所以 PropertiesLoaderUtils 比之于 Properties#load(InputStream inStream) 方法顯然具有更強(qiáng)的實(shí)用性。此外,PropertiesLoaderUtils 還可以直接從 Resource 對(duì)象中加載屬性資源:

方法說(shuō)明
static Properties loadProperties(Resource resource)從 Resource 中加載屬性
static void fillProperties(Properties props, Resource resource)將 Resource 中的屬性數(shù)據(jù)添加到一個(gè)已經(jīng)存在的 Properties 對(duì)象中

特殊編碼資源

當(dāng)您使用 Resource 實(shí)現(xiàn)類(lèi)加載文件資源時(shí),它默認(rèn)采用操作系統(tǒng)的編碼格式。如果文件資源采用了特殊的編碼格式(如 UTF-8),則在讀取資源內(nèi)容時(shí)必須事先通過(guò) EncodedResource 指定編碼格式,否則將會(huì)產(chǎn)生中文亂碼的問(wèn)題。

import org.springframework.core.io.ClassPathResource; 
 import org.springframework.core.io.Resource; 
 import org.springframework.core.io.support.EncodedResource; 
 import org.springframework.util.FileCopyUtils; 
 public class EncodedResourceExample { 
        public static void main(String[] args) throws Throwable  { 
            Resource res = new ClassPathResource("conf/file1.txt"); 
            // ① 指定文件資源對(duì)應(yīng)的編碼格式(UTF-8)
            EncodedResource encRes = new EncodedResource(res,"UTF-8"); 
            // ② 這樣才能正確讀取文件的內(nèi)容,而不會(huì)出現(xiàn)亂碼
            String content  = FileCopyUtils.copyToString(encRes.getReader()); 
            System.out.println(content);  
    } 
 }

EncodedResource 擁有一個(gè) getResource() 方法獲取 Resource,但該方法返回的是通過(guò)構(gòu)造函數(shù)傳入的原 Resource 對(duì)象,所以必須通過(guò) EncodedResource#getReader() 獲取應(yīng)用編碼后的 Reader 對(duì)象,然后再通過(guò)該 Reader 讀取文件的內(nèi)容。

創(chuàng)新互聯(lián)www.cdcxhl.cn,專(zhuān)業(yè)提供香港、美國(guó)云服務(wù)器,動(dòng)態(tài)BGP最優(yōu)骨干路由自動(dòng)選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機(jī)房獨(dú)有T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進(jìn)行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動(dòng)現(xiàn)已開(kāi)啟,新人活動(dòng)云服務(wù)器買(mǎi)多久送多久。

本文標(biāo)題:Spring3.0第四講:資源訪問(wèn)利器-Resource-創(chuàng)新互聯(lián)
分享URL:http://muchs.cn/article20/dgdhco.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)用戶體驗(yàn)、搜索引擎優(yōu)化域名注冊(cè)、企業(yè)建站、云服務(wù)器

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

綿陽(yáng)服務(wù)器托管