zoukankan      html  css  js  c++  java
  • 通过Spring Resource接口获取资源

    目录

    1       Resource简介

    2       通过ResourceLoader获取资源

    3       在bean中获取Resource的方式

    1       Resource简介

           在Spring内部,针对于资源文件有一个统一的接口Resource表示。其主要实现类有ClassPathResource、FileSystemResource、UrlResource、ByteArrayResource、ServletContextResource和InputStreamResource。Resource接口中主要定义有以下方法:

    l  exists():用于判断对应的资源是否真的存在。

    l  isReadable():用于判断对应资源的内容是否可读。需要注意的是当其结果为true的时候,其内容未必真的可读,但如果返回false,则其内容必定不可读。

    l  isOpen():用于判断当前资源是否代表一个已打开的输入流,如果结果为true,则表示当前资源的输入流不可多次读取,而且在读取以后需要对它进行关闭,以防止内存泄露。该方法主要针对于InputStreamResource,实现类中只有它的返回结果为true,其他都为false。

    l  getURL():返回当前资源对应的URL。如果当前资源不能解析为一个URL则会抛出异常。如ByteArrayResource就不能解析为一个URL。

    l  getFile():返回当前资源对应的File。如果当前资源不能以绝对路径解析为一个File则会抛出异常。如ByteArrayResource就不能解析为一个File。

    l  getInputStream():获取当前资源代表的输入流。除了InputStreamResource以外,其它Resource实现类每次调用getInputStream()方法都将返回一个全新的InputStream。

           ClassPathResource可用来获取类路径下的资源文件。假设我们有一个资源文件test.txt在类路径下,我们就可以通过给定对应资源文件在类路径下的路径path来获取它,new ClassPathResource(“test.txt”)。

           FileSystemResource可用来获取文件系统里面的资源。我们可以通过对应资源文件的文件路径来构建一个FileSystemResource。FileSystemResource还可以往对应的资源文件里面写内容,当然前提是当前资源文件是可写的,这可以通过其isWritable()方法来判断。FileSystemResource对外开放了对应资源文件的输出流,可以通过getOutputStream()方法获取到。

           UrlResource可用来代表URL对应的资源,它对URL做了一个简单的封装。通过给定一个URL地址,我们就能构建一个UrlResource。

           ByteArrayResource是针对于字节数组封装的资源,它的构建需要一个字节数组。

           ServletContextResource是针对于ServletContext封装的资源,用于访问ServletContext环境下的资源。ServletContextResource持有一个ServletContext的引用,其底层是通过ServletContext的getResource()方法和getResourceAsStream()方法来获取资源的。

           InputStreamResource是针对于输入流封装的资源,它的构建需要一个输入流。

    Java代码  
    1.    
    2. public class ResourceTest {  
    3.    
    4.    /** 
    5.     * ClassPathResource可以用来获取类路径下的资源 
    6.     * @throws IOException 
    7.     */  
    8.    @Test  
    9.    public void testClassPath() throws IOException {  
    10.       Resource resource = new ClassPathResource("test.txt");  
    11.       String fileName = resource.getFilename();  
    12.       System.out.println(fileName);  
    13. //    resource.getFile();   //获取资源对应的文件  
    14. //    resource.getURL(); //获取资源对应的URL  
    15.       if (resource.isReadable()) {  
    16.          //每次都会打开一个新的流  
    17.          InputStream is = resource.getInputStream();  
    18.          this.printContent(is);  
    19.       }  
    20.    }  
    21.     
    22.    /** 
    23.     * FileSystemResource可以用来获取文件系统里面的资源,对于FileSystemResource而言我们 
    24.     * 可以获取到其对应的输出流。 
    25.     * @throws IOException 
    26.     */  
    27.    @Test  
    28.    public void testFileSystem() throws IOException {  
    29.       FileSystemResource resource = new FileSystemResource("D:\test.txt");  
    30.       if (resource.isReadable()) {  
    31.          //FileInputStream  
    32.          printContent(resource.getInputStream());  
    33.       }  
    34.       if (resource.isWritable()) {  
    35.          //每次都会获取到一个新的输出流  
    36.          OutputStream os = resource.getOutputStream();  
    37.          BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));  
    38.          bw.write("你好,中国!");  
    39.          bw.flush();  
    40.          if (os != null) {  
    41.             os.close();  
    42.          }  
    43.          if (bw != null) {  
    44.             bw.close();  
    45.          }  
    46.       }  
    47.    }  
    48.     
    49.    /** 
    50.     * 针对于URL进行封装的Resource,可用来从URL获取资源内容 
    51.     * @throws Exception 
    52.     */  
    53.    @Test  
    54.    public void testURL() throws Exception {  
    55.       UrlResource resource = new UrlResource("http://www.google.com.hk");  
    56.       if (resource.isReadable()) {  
    57.          //URLConnection对应的getInputStream()。  
    58.          printContent(resource.getInputStream());  
    59.       }  
    60.    }  
    61.     
    62.    /** 
    63.     * 针对于字节数组封装的Resource,用来从字节数组获取资源内容 
    64.     * @throws IOException 
    65.     */  
    66.    @Test  
    67.    public void testByteArray() throws IOException {  
    68.       ByteArrayResource resource = new ByteArrayResource("Hello".getBytes());  
    69.       //ByteArrayInputStream()  
    70.       printContent(resource.getInputStream());  
    71.    }  
    72.     
    73.    /** 
    74.     * 针对于输入流的Resource,其getInputStream()方法只能被调用一次。 
    75.     * @throws Exception 
    76.     */  
    77.    @Test  
    78.    public void testInputStream() throws Exception {  
    79.       InputStream is = new FileInputStream("D:\test.txt");  
    80.       InputStreamResource resource = new InputStreamResource(is);  
    81.       //对于InputStreamResource而言,其getInputStream()方法只能调用一次,继续调用将抛出异常。  
    82.       InputStream target = resource.getInputStream();   //返回的就是构件时的那个InputStream  
    83.       //is将在printContent方法里面进行关闭  
    84.       printContent(target);  
    85.    }  
    86.     
    87.    /** 
    88.     * 输出输入流的内容 
    89.     * @param is 
    90.     * @throws IOException 
    91.     */  
    92.    private void printContent(InputStream is) throws IOException {  
    93.       BufferedReader br = new BufferedReader(new InputStreamReader(is));  
    94.       String line;  
    95.       while ((line=br.readLine()) != null) {  
    96.          System.out.println(line);  
    97.       }  
    98.       if (is != null) {  
    99.          is.close();  
    100.       }  
    101.       if (br != null) {  
    102.          br.close();  
    103.       }  
    104.    }  
    105.     
    106. }  

    2       通过ResourceLoader获取资源

           在Spring里面还定义有一个ResourceLoader接口,该接口中只定义了一个用于获取Resource的getResource(String location)方法。它的实现类有很多,这里我们先挑一个DefaultResourceLoader来讲。DefaultResourceLoader在获取Resource时采用的是这样的策略:首先判断指定的location是否含有“classpath:”前缀,如果有则把location去掉“classpath:”前缀返回对应的ClassPathResource;否则就把它当做一个URL来处理,封装成一个UrlResource进行返回;如果当成URL处理也失败的话就把location对应的资源当成是一个ClassPathResource进行返回。

    Java代码  
    1. @Test  
    2. public void testResourceLoader() {  
    3.    ResourceLoader loader = new DefaultResourceLoader();  
    4.    Resource resource = loader.getResource("http://www.google.com.hk");  
    5.    System.out.println(resource instanceof UrlResource); //true  
    6.    //注意这里前缀不能使用“classpath*:”,这样不能真正访问到对应的资源,exists()返回false  
    7.    resource = loader.getResource("classpath:test.txt");  
    8.    System.out.println(resource instanceof ClassPathResource); //true  
    9.    resource = loader.getResource("test.txt");  
    10.    System.out.println(resource instanceof ClassPathResource); //true  
    11. }  

           ApplicationContext接口也继承了ResourceLoader接口,所以它的所有实现类都实现了ResourceLoader接口,都可以用来获取Resource。

           对于ClassPathXmlApplicationContext而言,它在获取Resource时继承的是它的父类DefaultResourceLoader的策略。

           FileSystemXmlApplicationContext也继承了DefaultResourceLoader,但是它重写了DefaultResourceLoader的getResourceByPath(String path)方法。所以它在获取资源文件时首先也是判断指定的location是否包含“classpath:”前缀,如果包含,则把location中“classpath:”前缀后的资源从类路径下获取出来,当做一个ClassPathResource;否则,继续尝试把location封装成一个URL,返回对应的UrlResource;如果还是失败,则把location指定位置的资源当做一个FileSystemResource进行返回。

    3       在bean中获取Resource的方式

           通过上面内容的介绍,我们知道,在bean中获取Resource主要有以下几种方式:

           1.直接通过new各种类型的Resource来获取对应的Resource。

           2.在bean里面获取到对应的ApplicationContext,再通过ApplicationContext的getResource(String path)方法获取对应的Resource。

         3.直接创建DefaultResourceLoader的实例,再调用其getResource(String location)方法获取对应的Resource。

           4.通过依赖注入的方式把Resource注入到bean中。示例如下:

    类ClassA

    Java代码  
    1. public class ClassA {  
    2.    
    3.    //持有一个Resource属性  
    4.    private Resource resource;  
    5.     
    6.    public void printContent() {  
    7.       if (resource != null && resource.exists()) {  
    8.          if (resource.isReadable()) {  
    9.             InputStream is;  
    10.             try {  
    11.                 is = resource.getInputStream();  
    12.                 BufferedReader br = new BufferedReader(new InputStreamReader(is));  
    13.                 String line;  
    14.                 while ((line=br.readLine()) != null) {  
    15.                    System.out.println(line);  
    16.                 }  
    17.                 if (is != null) {  
    18.                    is.close();  
    19.                 }  
    20.                 if (br != null) {  
    21.                    br.close();  
    22.                 }  
    23.             } catch (IOException e) {  
    24.                 e.printStackTrace();  
    25.             }  
    26.          }  
    27.       }  
    28.    }  
    29.     
    30.    public void setResource(Resource resource) {  
    31.       this.resource = resource;  
    32.    }  
    33.     
    34. }  

    applicationContext.xml文件:

    Xml代码  
    1. <?xml version="1.0" encoding="UTF-8"?>   
    2. <beans xmlns="http://www.springframework.org/schema/beans"   
    3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"   
    4.     xsi:schemaLocation="http://www.springframework.org/schema/beans   
    5.          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd   
    6.          http://www.springframework.org/schema/context   
    7.          http://www.springframework.org/schema/context/spring-context-3.0.xsd">   
    8.    
    9.    <bean id="classA" class="com.xxx.ClassA">  
    10.       <property name="resource">  
    11.          <value>classpath:applicationContext.xml</value>  
    12.       </property>  
    13.    </bean>  
    14.    
    15. </beans>  

           从上面可以看到我们有一个类ClassA,其持有一个Resource属性,在Spring bean配置文件中我们直接给ClassA注入了属性resource。其对应的测试代码如下:

    Java代码  
    1. @RunWith(SpringJUnit4ClassRunner.class)  
    2. @ContextConfiguration("classpath:applicationContext.xml")  
    3. public class Test1 {  
    4.    
    5.    @Autowired  
    6.    private ClassA classA;  
    7.     
    8.    @Test  
    9.    public void test() {  
    10.       classA.printContent();  
    11.    }  
    12.     
  • 相关阅读:
    237. Delete Node in a Linked List
    430. Flatten a Multilevel Doubly Linked List
    707. Design Linked List
    83. Remove Duplicates from Sorted List
    160. Intersection of Two Linked Lists
    426. Convert Binary Search Tree to Sorted Doubly Linked List
    142. Linked List Cycle II
    类之间的关系
    初始化块
    明确类和对象
  • 原文地址:https://www.cnblogs.com/wcss/p/12374016.html
Copyright © 2011-2022 走看看