通过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是针对于输入流封装的资源,它的构建需要一个输入流。
- 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接口,该接口中只定义了一个用于获取Resource的getResource(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,但是它重写了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:
- 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();
- }
通过Spring Resource接口获取资源的更多相关文章
- Spring Resource接口获取资源
1.1.1. Resource简介 在Spring内部实现机制,针对于资源文件(配置的xml文件)有一个统一的接口Resource. 1.1.1.1. 接口定义的方法 1.exists():判断资源文 ...
- Bean利用Resource接口获取资源的几种方式
Resources的类型 获取resource的方式(xml配置正常进行):
- [Spring] Resource 资源
import ch.qos.logback.core.net.SyslogOutputStream; import org.springframework.core.io.ClassPathResou ...
- Spring源码分析——资源访问利器Resource之接口和抽象类分析
从今天开始,一步步走上源码分析的路.刚开始肯定要从简单着手.我们先从Java发展史上最强大的框架——Spring...旗下的资源抽象接口Resource开始吧. 我看了好多分析Spring源码的,每每 ...
- 攻城狮在路上(贰) Spring(三)--- Spring 资源访问利器Resource接口
Spring为了更好的满足各种底层资源的访问需求.设计了一个Resource接口,提供了更强的访问底层资源的能力.Spring框架使用Resource装载各种资源,包括配置文件资源.国际化属性文件资源 ...
- Spring源码分析——资源访问利器Resource之实现类分析
今天来分析Spring的资源接口Resource的各个实现类.关于它的接口和抽象类,参见上一篇博文——Spring源码分析——资源访问利器Resource之接口和抽象类分析 一.文件系统资源 File ...
- spring资源访问接口和资源加载接口
spring 资源访问接口 JDK提供的资源访问类,如java.net.URL.File等,不能很好地满足各种资源的访问需求,比如缺少从类路径或者Web容器的上下文中获取资源的操作类. 鉴于此,spr ...
- Resource接口,及资源
Resource介绍 编码的时候,除了代码本身,我们还需要对外部的资源进行处理.例如:URL资源.URI资源.File资源.ClassPath相关资源.服务器相关资源(VFS等)等等. 而这些资源的处 ...
- 基础篇:JAVA资源之IO、字符编码、URL和Spring.Resource
目录 1 JAVA.IO字节流 2 JAVA.IO字符流 3 乱码问题和字符流 4 字符集和字符编码的概念区分 5 URI概念的简单介绍 6 URL概念及与URL的区别 7 Spring.Resour ...
随机推荐
- 取Cookie值
string url_Login_Group = "http://ui.ptlogin2.qq.com/cgi-bin/login?appid=549000912&daid=5&am ...
- codechef Future of draughts
难度 super-hard 题意 官方中文题意 做法 定义1:\(G\)为邻接矩阵,\(I\)为单位矩阵 定义2:\(H\)为转移矩阵,可以不动,即\(H=G+I\) 定义3:\(e_i(x_1,.. ...
- mysql 数据库优化的几种方法
1.选取最适用的字段属性 MySQL可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快.因此,在创建表的时候,为了获得更好的性能,我们可以将表中字段的宽度设得尽 ...
- python3练习100题——050
题目:输出一个随机数. 程序分析:使用 random 模块. import random print( random.randint(1,10) ) # 产生 1 到 10 的一个整数型随机数 pri ...
- php如何获取单选复选和选择框的值
1.很久没有写基础的东西了复习一下(往往简单的东西才复杂) <body> 选择语句 <form action="demo.php" method="po ...
- jQuery---清空节点和删除节点
清空节点和删除节点 //可以清空一个元素的内容 //清理门户 $("div").empty(); //完全移除元素 $("div").remove(); $(f ...
- 51 nod1067 Bash游戏 V2(sg函数打表)
1067 Bash游戏 V2 1.0 秒 131,072.0 KB 5 分 1级题 有一堆石子共有N个.A B两个人轮流拿,A先拿.每次只能拿1,3,4颗,拿到最后1颗石子的人获胜.假设A B都非 ...
- BZOJ的思维题
5085:最大 给你一个n×m的矩形,要你找一个子矩形,价值为左上角左下角右上角右下角这四个数的最小值,要你最大化矩形 的价值. 关键点是要想到把这些值排序 值从小到大考虑,比如说现在最小的值是(x1 ...
- C语言移除链表元素
删除链表中等于给定值 val 的所有节点. 示例: 输入: 1->2->6->3->4->5->6, val = 6 输出: 1->2->3->4 ...
- Hive学习笔记二
目录 Hive常见属性配置 将本地库文件导入Hive案例 Hive常用交互命令 Hive其他命令操作 参数配置方式 Hive常见属性配置 1.Hive数据仓库位置配置 1)Default数据仓库的最原 ...