`
234390216
  • 浏览: 10192394 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
博客专栏
A5ee55b9-a463-3d09-9c78-0c0cf33198cd
Oracle基础
浏览量:460747
Ad26f909-6440-35a9-b4e9-9aea825bd38e
springMVC介绍
浏览量:1771676
Ce363057-ae4d-3ee1-bb46-e7b51a722a4b
Mybatis简介
浏览量:1395339
Bdeb91ad-cf8a-3fe9-942a-3710073b4000
Spring整合JMS
浏览量:393855
5cbbde67-7cd5-313c-95c2-4185389601e7
Ehcache简介
浏览量:678187
Cc1c0708-ccc2-3d20-ba47-d40e04440682
Cas简介
浏览量:529242
51592fc3-854c-34f4-9eff-cb82d993ab3a
Spring Securi...
浏览量:1178648
23e1c30e-ef8c-3702-aa3c-e83277ffca91
Spring基础知识
浏览量:461678
4af1c81c-eb9d-365f-b759-07685a32156e
Spring Aop介绍
浏览量:150089
2f926891-9e7a-3ce2-a074-3acb2aaf2584
JAXB简介
浏览量:66813
社区版块
存档分类
最新评论

通过Spring Resource接口获取资源

阅读更多

通过Spring Resource接口获取资源

目录

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();
   }
  
}

 

 

 

 

6
3
分享到:
评论

相关推荐

    Spring 2.0 开发参考手册

    5.2. 使用Spring的Validator接口进行校验 5.3. 从错误代码到错误信息 5.4. Bean处理和BeanWrapper 5.4.1. 设置和获取属性值以及嵌套属性 5.4.2. 内建的PropertyEditor实现 6. 使用Spring进行面向切面编程(AOP...

    Spring-Reference_zh_CN(Spring中文参考手册)

    5.2. 使用Spring的Validator接口进行校验 5.3. 从错误代码到错误信息 5.4. Bean处理和BeanWrapper 5.4.1. 设置和获取属性值以及嵌套属性 5.4.2. 内建的PropertyEditor实现 5.4.2.1. 注册用户自定义的PropertyEditor ...

    spring chm文档

    5.2. 使用Spring的Validator接口进行校验 5.3. 从错误代码到错误信息 5.4. Bean处理和BeanWrapper 5.4.1. 设置和获取属性值以及嵌套属性 5.4.2. 内建的PropertyEditor实现 6. 使用Spring进行面向切面编程(AOP...

    Spring中文帮助文档

    4.2. Resource接口 4.3. 内置 Resource 实现 4.3.1. UrlResource 4.3.2. ClassPathResource 4.3.3. FileSystemResource 4.3.4. ServletContextResource 4.3.5. InputStreamResource 4.3.6. ByteArrayResource...

    Spring API

    4.2. Resource接口 4.3. 内置 Resource 实现 4.3.1. UrlResource 4.3.2. ClassPathResource 4.3.3. FileSystemResource 4.3.4. ServletContextResource 4.3.5. InputStreamResource 4.3.6. ByteArrayResource...

    Spring攻略(第二版 中文高清版).part2

    10.4 通过BlazeDS/Spring暴露服务 411 10.4.1 问题 411 10.4.2 解决方案 411 10.4.3 工作原理 411 10.5 使用服务器端对象 418 10.5.1 问题 418 10.5.2 解决方案 418 10.5.3 工作原理 418 10.6 使用...

    Spring攻略(第二版 中文高清版).part1

    10.4 通过BlazeDS/Spring暴露服务 411 10.4.1 问题 411 10.4.2 解决方案 411 10.4.3 工作原理 411 10.5 使用服务器端对象 418 10.5.1 问题 418 10.5.2 解决方案 418 10.5.3 工作原理 418 10.6 使用...

    spring-common:[已弃用]与Spring Boot应用程序一起使用的通用Spring组件库和相关类

    Spring常见 我的Spring Boot应用程序中使用的通用Spring组件库和相关类库 介绍 ... 查询以获取List功能接口 用法 资源阅读器 package foo; import net.kemitix.spring.common.ResourceReader; @Compon

    【分布式事务----LCN】LCN原理及使用方式.docx

    TCC事务机制相对于传统事务机制(X/Open XA Two-Phase-Commit),其特征在于它不依赖资源管理器(RM)对XA的支持,而是通过对(由业务系统提供的)业务逻辑的调度来实现分布式事务。主要由三步操作,Try: 尝试执行业务...

    基于Java开发的员工考勤管理系统源码-Web版+数据库sql+项目说明+设计报告.zip

    - Postman:接口测试 - MySQL:关系型数据库 - Astah:UML 建模环境 - Git/Gitee:代码版本控制 ## 5. 项目部署 - 本项目基于 Windows10 系统运行 ### 5.1 数据库部署 1. 确保 MySQL 已安装(v8.0.25)并启动...

    乐优商城.xmind

    GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源 BUG 分类不能打开,当添加后却能打开。 修改一天的BUG 最后发现是实体类里属性大小写的问题引起。 注意 Bule_bird 就必须写成 ...

    cms后台管理

    //获取内容列表,可以通过此处进行更改,获取自己数据库中的数据 List&lt;Content&gt; list = getList(params, env); Map, TemplateModel&gt; paramWrap = new HashMap, TemplateModel&gt;( params); //OUT_LIST值为tag_...

    J2EE应用开发详解

    29 3.2.2 Class.forName()加载类的实例 30 3.2.3 loadClass获得类的实例 31 3.3 操作类的字段 31 3.3.1 获取对象的属性 31 3.4 操作类的方法 34 3.4.1 运行时调用对象的方法 34 3.4.2 无参构造函数 36 3.4.3 带参...

    IBM portlet开发指南

    BaseURL 接口 ................................................................................................................. 57 包含Portlet Mode和 Window State信息 .....................................

Global site tag (gtag.js) - Google Analytics