通过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(); } }
相关推荐
5.2. 使用Spring的Validator接口进行校验 5.3. 从错误代码到错误信息 5.4. Bean处理和BeanWrapper 5.4.1. 设置和获取属性值以及嵌套属性 5.4.2. 内建的PropertyEditor实现 6. 使用Spring进行面向切面编程(AOP...
5.2. 使用Spring的Validator接口进行校验 5.3. 从错误代码到错误信息 5.4. Bean处理和BeanWrapper 5.4.1. 设置和获取属性值以及嵌套属性 5.4.2. 内建的PropertyEditor实现 5.4.2.1. 注册用户自定义的PropertyEditor ...
5.2. 使用Spring的Validator接口进行校验 5.3. 从错误代码到错误信息 5.4. Bean处理和BeanWrapper 5.4.1. 设置和获取属性值以及嵌套属性 5.4.2. 内建的PropertyEditor实现 6. 使用Spring进行面向切面编程(AOP...
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...
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...
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 使用...
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常见 我的Spring Boot应用程序中使用的通用Spring组件库和相关类库 介绍 ... 查询以获取List功能接口 用法 资源阅读器 package foo; import net.kemitix.spring.common.ResourceReader; @Compon
TCC事务机制相对于传统事务机制(X/Open XA Two-Phase-Commit),其特征在于它不依赖资源管理器(RM)对XA的支持,而是通过对(由业务系统提供的)业务逻辑的调度来实现分布式事务。主要由三步操作,Try: 尝试执行业务...
- Postman:接口测试 - MySQL:关系型数据库 - Astah:UML 建模环境 - Git/Gitee:代码版本控制 ## 5. 项目部署 - 本项目基于 Windows10 系统运行 ### 5.1 数据库部署 1. 确保 MySQL 已安装(v8.0.25)并启动...
GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源 BUG 分类不能打开,当添加后却能打开。 修改一天的BUG 最后发现是实体类里属性大小写的问题引起。 注意 Bule_bird 就必须写成 ...
//获取内容列表,可以通过此处进行更改,获取自己数据库中的数据 List<Content> list = getList(params, env); Map, TemplateModel> paramWrap = new HashMap, TemplateModel>( params); //OUT_LIST值为tag_...
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 带参...
BaseURL 接口 ................................................................................................................. 57 包含Portlet Mode和 Window State信息 .....................................