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

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 通过Spring Resource接口获取资源

一、Resources介绍

Resources :获取资源文件的统一接口。

二、Resources接口主要实现类有

ClassPathResource:获取类路径下的资源文件
UrlResource:URL对应的资源,根据一个URL地址即可创建
FileSystemResource:获取文件系统里面的资源
ServletContextResource:ServletContext封装的资源,用于访问
ServletContext环境下的资源
InputStreamResource:针对输入流封装的资源
ByteArrayResource:针对于字节数封装的资源
三、Resource接口中主要定义有以下方法

exists():用于判断对应的资源是否真的存在。
isReadable():用于判断对应资源的内容是否可读。需要注意的是当其结果为true的时候,其内容未必真的可读,但如果返回false,则其内容必定不可读。
isOpen():用于判断当前资源是否代表一个已打开的输入流,如果结果为true,则表示当前资源的输入流不可多次读取,而且在读取以后需要对它进行关闭,以防止内存泄露。该方法主要针对于InputStreamResource,实现类中只有它的返回结果为true,其他都为false。
getURL():返回当前资源对应的URL。如果当前资源不能解析为一个URL则会抛出异常。如ByteArrayResource就不能解析为一个URL。
getFile():返回当前资源对应的File。如果当前资源不能以绝对路径解析为一个File则会抛出异常。如ByteArrayResource就不能解析为一个File。
getInputStream():获取当前资源代表的输入流,除了InputStreamResource以外,其它Resource实现类每次调用getInputStream()方法都将返回一个全新的InputStream。
四、在bean中获取Resource的方式有以下四种方式

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

      /** 
        * ClassPathResource可以用来获取类路径下的资源 
        * @throws IOException 
        */  
       @Test  
       public void testClassPath() throws IOException {  
          Resource resource = new ClassPathResource("spring-ioc.xml");  
          String fileName = resource.getDescription();  
          System.out.println(fileName);  

          if (resource.isReadable()) {  
             //每次都会打开一个新的流  
             InputStream is = resource.getInputStream();  
             this.printContent(is);  
          }  
       }  

       /** 
        * FileSystemResource可以用来获取文件系统里面的资源,
        * 对于FileSystemResource而言我们可以获取到其对应的输出流OutputStream。 
        * @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("FileSystemResource实现类测试。");  
             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.baidu.com");  
          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、直接创建DefaultResourceLoader的实例,再调用其getResource(String location)方法获取对应的Resource。

在spring里面定义有一个ResourceLoader接口,该接口中只定义了一个用于获取Resource的getResource(String location)方法。

DefaultResourceLoader在获取Resource时采用的是这样的策略:首先判断指定的location是否含有“classpath:”前缀,如果有则把location去掉“classpath:”前缀返回对应的ClassPathResource;否则就把它当做一个URL来处理,封装成一个UrlResource进行返回;如果当成URL处理也失败的话就把location对应的资源当成是一个ClassPathResource进行返回。

    @Test  
    public void testDefaultResourceLoader() {  
        //ResourceLoader还可以通过实现ResourceLoaderAware接口或者使用@Autowired注解注入的方式获取
       ResourceLoader loader = new DefaultResourceLoader();  
       Resource resource = loader.getResource("http://www.baidu.com");  
       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  
    }

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

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

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

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

@Test
    public void testContextResource() throws IOException{
        //获取spring上下文
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-ioc.xml");

        //通过spring context获取Resource
        Resource resource = context.getResource("classpath:spring-ioc.xml");
        if (resource.isReadable()) {  
             //URLConnection对应的getInputStream()。  
             printContent(resource.getInputStream());  
          }  
    }

4、通过依赖注入的方式把Resource注入到bean中。

    <bean name ="injectResource" class="com.jsun.test.springDemo.bean.InjectResource">
        <!-- 采用setter注入的方式,注入resource -->
        <property name="resource">
            <value>classpath:spring-ioc.xml</value>
        </property>
    </bean>

public class InjectResource {
    //声明resource以及setter方法
    private Resource resource;

    public void setResource(Resource resource) {
        this.resource = resource;
    }

    //读取资源
    public void injectResource() throws IOException{
        if (resource.isReadable()) {  
             //URLConnection对应的getInputStream()。  
             printContent(resource.getInputStream());  
         }
    }

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

    @Test
    public void testInjectResource() throws IOException{
        InjectResource injectResource = super.getBean("injectResource");
        injectResource.injectResource();
    }

作者:glowd
原文:https://blog.csdn.net/zengqiang1/article/details/54601235
版权声明:本文为博主原创文章,转载请附上博文链接!

相关文章
|
7天前
|
存储 安全 Java
|
21天前
|
自然语言处理 JavaScript Java
Spring 实现 3 种异步流式接口,干掉接口超时烦恼
本文介绍了处理耗时接口的几种异步流式技术,包括 `ResponseBodyEmitter`、`SseEmitter` 和 `StreamingResponseBody`。这些工具可在执行耗时操作时不断向客户端响应处理结果,提升用户体验和系统性能。`ResponseBodyEmitter` 适用于动态生成内容场景,如文件上传进度;`SseEmitter` 用于实时消息推送,如状态更新;`StreamingResponseBody` 则适合大数据量传输,避免内存溢出。文中提供了具体示例和 GitHub 地址,帮助读者更好地理解和应用这些技术。
115 0
|
2月前
|
存储 数据采集 Java
Spring Boot 3 实现GZIP压缩优化:显著减少接口流量消耗!
在Web开发过程中,随着应用规模的扩大和用户量的增长,接口流量的消耗成为了一个不容忽视的问题。为了提升应用的性能和用户体验,减少带宽占用,数据压缩成为了一个重要的优化手段。在Spring Boot 3中,通过集成GZIP压缩技术,我们可以显著减少接口流量的消耗,从而优化应用的性能。本文将详细介绍如何在Spring Boot 3中实现GZIP压缩优化。
203 6
|
1月前
|
存储 NoSQL Java
Spring Boot项目中使用Redis实现接口幂等性的方案
通过上述方法,可以有效地在Spring Boot项目中利用Redis实现接口幂等性,既保证了接口操作的安全性,又提高了系统的可靠性。
28 0
|
3月前
|
JSON 安全 Java
|
3月前
|
存储 SQL Java
|
3月前
|
前端开发 JavaScript Java
Spring Boot应用中的资源分离与高效打包实践
通过实施资源分离和高效打包策略,不仅可以提升Spring Boot应用的开发和部署效率,还能显著提高用户体验。在实际项目中,根据项目的实际情况和团队的技术栈选择合适的工具和方案是关键。希望本文能为读者在Spring Boot项目中实现资源分离和高效打包提供一些有价值的参考。
|
3月前
|
JavaScript Java Spring
Spring Boot 接口返回文件流
Spring Boot 接口返回文件流
94 0
|
4月前
|
SQL Java 数据库
实时计算 Flink版产品使用问题之Spring Boot集成Flink可以通过什么方式实现通过接口启动和关闭Flink程序
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
5月前
|
Java 开发者 Spring
Spring项目中Ordered接口的应用:全局过滤器(GlobalFilter)的顺序控制
Spring项目中Ordered接口的应用:全局过滤器(GlobalFilter)的顺序控制
202 2