`
喜欢蓝色的我
  • 浏览: 370884 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

通过Spring Resource接口获取资源(转)

    博客分类:
  • java
 
阅读更多

目录

1       Resource简介

2       通过ResourceLoader获取资源

3       bean中获取Resource的方式

 

1       Resource简介

       Spring内部,针对于资源文件有一个统一的接口Resource表示。其主要实现类有ClassPathResourceFileSystemResourceUrlResourceByteArrayResourceServletContextResourceInputStreamResourceResource接口中主要定义有以下方法:

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

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

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

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

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

 
public class ResourceTest {
 
   /**
    * ClassPathResource可以用来获取类路径下的资源
    * @throws IOException
    */
   @Test
   public void testClassPath() throws IOException {
      Resource resource = new ClassPathResource("test.txt");
      String fileName = resource.getFilename();
      System.out.println(fileName);
//    resource.getFile();   //获取资源对应的文件
//    resource.getURL(); //获取资源对应的URL
      if (resource.isReadable()) {
         //每次都会打开一个新的流
         InputStream is = resource.getInputStream();
         this.printContent(is);
      }
   }
 
   /**
    * FileSystemResource可以用来获取文件系统里面的资源,对于FileSystemResource而言我们
    * 可以获取到其对应的输出流。
    * @throws IOException
    */
   @Test
   public void testFileSystem() throws IOException {
      FileSystemResource resource = new FileSystemResource("D:\\test.txt");
      if (resource.isReadable()) {
         //FileInputStream
         printContent(resource.getInputStream());
      }
      if (resource.isWritable()) {
         //每次都会获取到一个新的输出流
         OutputStream os = resource.getOutputStream();
         BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
         bw.write("你好,中国!");
         bw.flush();
         if (os != null) {
            os.close();
         }
         if (bw != null) {
            bw.close();
         }
      }
   }
 
   /**
    * 针对于URL进行封装的Resource,可用来从URL获取资源内容
    * @throws Exception
    */
   @Test
   public void testURL() throws Exception {
      UrlResource resource = new UrlResource("http://www.google.com.hk");
      if (resource.isReadable()) {
         //URLConnection对应的getInputStream()。
         printContent(resource.getInputStream());
      }
   }
 
   /**
    * 针对于字节数组封装的Resource,用来从字节数组获取资源内容
    * @throws IOException
    */
   @Test
   public void testByteArray() throws IOException {
      ByteArrayResource resource = new ByteArrayResource("Hello".getBytes());
      //ByteArrayInputStream()
      printContent(resource.getInputStream());
   }
 
   /**
    * 针对于输入流的Resource,其getInputStream()方法只能被调用一次。
    * @throws Exception
    */
   @Test
   public void testInputStream() throws Exception {
      InputStream is = new FileInputStream("D:\\test.txt");
      InputStreamResource resource = new InputStreamResource(is);
      //对于InputStreamResource而言,其getInputStream()方法只能调用一次,继续调用将抛出异常。
      InputStream target = resource.getInputStream();   //返回的就是构件时的那个InputStream
      //is将在printContent方法里面进行关闭
      printContent(target);
   }
 
   /**
    * 输出输入流的内容
    * @param is
    * @throws IOException
    */
   private void printContent(InputStream is) throws IOException {
      BufferedReader br = new BufferedReader(new InputStreamReader(is));
      String line;
      while ((line=br.readLine()) != null) {
         System.out.println(line);
      }
      if (is != null) {
         is.close();
      }
      if (br != null) {
         br.close();
      }
   }
 
}

 

2       通过ResourceLoader获取资源

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

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

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

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

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

 

3       bean中获取Resource的方式

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

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

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

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

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

 

ClassA

public class ClassA {
 
   //持有一个Resource属性
   private Resource resource;
 
   public void printContent() {
      if (resource != null && resource.exists()) {
         if (resource.isReadable()) {
            InputStream is;
            try {
                is = resource.getInputStream();
                BufferedReader br = new BufferedReader(new InputStreamReader(is));
                String line;
                while ((line=br.readLine()) != null) {
                   System.out.println(line);
                }
                if (is != null) {
                   is.close();
                }
                if (br != null) {
                   br.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
         }
      }
   }
 
   public void setResource(Resource resource) {
      this.resource = resource;
   }
 
}

 

applicationContext.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context-3.0.xsd">
 
   <bean id="classA" class="com.xxx.ClassA">
      <property name="resource">
         <value>classpath:applicationContext.xml</value>
      </property>
   </bean>
 
</beans>

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

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Test1 {
 
   @Autowired
   private ClassA classA;
 
   @Test
   public void test() {
      classA.printContent();
   }
 
}

源:http://haohaoxuexi.iteye.com/blog/2016305

分享到:
评论

相关推荐

    spring Resource管理详解

    Spring的Resource接口是访问资源的抽象,它提供了一种统一的资源访问方式,可以处理不同来源的资源,包括本地文件系统、类路径、URL等。Resource对象并不直接包含资源内容,而是提供了打开输入流、获取资源路径等...

    Spring_ClassPathResource获得bean对象

    在Spring框架中,ClassPathResource是获取类路径资源的一个重要工具。它允许我们从类路径(classpath)中读取文件,如配置文件、属性文件等,这对于构建和管理Java应用程序非常有用。本篇文章将深入探讨如何使用Spring...

    spring-resource

    除了基本的读取操作,`Resource`还支持其他方法,如`exists()`检查资源是否存在,`isReadable()`判断是否可读,`getURI()`获取资源的URI,`getFileName()`获取文件名等,这些都是在处理资源时可能用到的功能。...

    spring中的资源访问宝典

    本文将详细介绍Spring如何通过`Resource`接口及其实现类来简化资源的访问。 首先,传统的资源访问方式通常依赖于`java.net.URL`和文件I/O操作,这种方式不仅代码复杂,而且效率较低。例如,在`URLTest`类中,我们...

    获取Spring容器

    ### 获取Spring容器的...通过以上介绍,我们可以了解到如何在Spring应用中通过编程的方式手动获取Spring容器中的对象。这种方式为开发者提供了更大的灵活性,但也需要谨慎使用,以避免引入不必要的复杂性和性能问题。

    19 Spring MVC应用拓展Resource应用于文件下载慕课专栏1

    Resource接口是Spring提供的,用于抽象资源的访问,它可以是文件、URL、类路径下的资源等。通过Resource的实现类,如FileSystemResource或ClassPathResource,我们可以轻松地获取到文件的InputStream。 例如,对于...

    spring3.x 实战资源教程

    - **Resource接口**:Spring提供了一个统一的Resource接口来访问不同类型的资源。 - **ResourceLoader接口**:提供了获取Resource的方法,通常由ApplicationContext实现。 #### 3.2 内置Resource实现 - **ClassPath...

    Spring实战之使用ClassPathResource加载xml资源示例

    接着,通过`getFilename()`和`getDescription()`方法获取资源的基本信息: ```java System.out.println(cr.getFilename()); System.out.println(cr.getDescription()); ``` 然后,使用DOM4J库的`SAXReader`解析XML...

    Spring文件资源操作和Web相关工具类盘点

    此外,Resource 接口还提供了 URL 和 URI 的获取方法,方便进行网络资源的处理。例如,如果您需要获取文件的 URL 地址,可以调用 `getURL()` 方法。 Spring 提供的 Resource 实现类不仅仅限于 FileSystemResource ...

    Spring实战之ServletContextResource访问资源文件示例

    接着,我们可以获取资源的一些基本信息,如文件名和描述: ```java System.out.println(src.getFilename()); System.out.println(src.getDescription()); ``` `getFilename()`返回资源的文件名,`getDescription()...

    Spring5中文文档

    资源管理章节涵盖了资源的获取和抽象,包括Resource接口的介绍、内置的Resource实现、资源加载器以及如何在应用上下文中使用资源路径。 验证、数据绑定和类型转换部分讲解了如何使用Spring的验证器接口进行验证,...

    spring源码包.zip

    `spring-core`模块包含了Spring的基本工具类和基础设施,如Resource接口、ConversionService接口等,为整个Spring框架提供了基础服务。此外,它还引入了ResourceLoader,用于加载各种类型的资源,如文件、URL、...

    跟我学Spring3(4.1)资源之基础知识Java开发J

    通过`Resource`接口,Spring提供了一种统一的方式来读取和操作这些资源。例如,开发者可以方便地读取类路径下的配置文件,或者从网络上获取远程数据。 Spring的IoC容器负责管理和配置应用程序的bean,而资源管理则...

    Spring实战之使用Resource作为属性操作示例

    Resource接口提供了几个方法,用于获取资源的信息,例如获取资源的名称、描述、URL等。 使用Resource作为属性 在Spring中,我们可以使用Resource作为Bean的属性,从而实现对资源的访问和操作。例如,在上面的代码...

    spring资源文件

    4. **资源加载**:Spring使用`Resource`接口来表示资源,它可以是文件、URL、输入/输出流等。`ClassPathResource`、`FileSystemResource`和`UrlResource`是其常见实现,分别用于加载类路径、文件系统和URL路径的资源...

    spring读取jar中的配置文件

    此外,Spring还提供了`Resource`接口,允许我们直接访问JAR内的资源。例如,我们可以这样做: ```java @Autowired private ResourceLoader resourceLoader; public void readConfigFile() throws IOException { ...

    spring_FrameWork3.0

    - **ResourceLoaderAware 接口:** 允许 Bean 获得 ResourceLoader,以便在 Bean 中直接使用 ResourceLoader 获取资源。 - **Resources 依赖:** 在 Bean 的定义中可以通过 Resource 来引用其他资源。 - **...

    spring-framework-4-reference

    Resource接口的引入提供了统一的访问方式,不论资源位于何处。Spring还提供了一种资源加载器(ResourceLoader),用于根据具体路径类型加载Resource对象。 Validation, Data Binding, and Type Conversion部分讲解...

    spring security oauth2.0 (讲义+代码)

    首先,OAuth2.0 有四个核心角色:资源所有者(Resource Owner)、客户端(Client)、资源服务器(Resource Server)和授权服务器(Authorization Server)。资源所有者是拥有受保护资源的用户,客户端是请求访问资源...

Global site tag (gtag.js) - Google Analytics