Spring资源抽象接口
JDK所提供的访问资源的类(如java.net.URL、File等)并不能很好地满足各种底层资源的访问需求,比如缺少从类路径或者Web容器的上下文获取资源的操作类。有鉴于此,Spring设计了一个Resource接口,它为应用提供了更强的访问底层资源的能力。该接口拥有对应不同资源类型的实现类。先来了解一下Resource接口的主要方法:
public interface InputStreamSource { //每次调用都将返回一个新鲜的资源对应的java.io. InputStream字节流, //调用者在使用完毕后必须关闭该资源。 InputStream getInputStream() throws IOException; }
public interface Resource extends InputStreamSource { //资源是否存在。 boolean exists(); //是否可以读 boolean isReadable(); //资源是否打开 boolean isOpen(); //如果底层资源可以表示为urL,则返回url对象 URL getURL() throws IOException; URI getURI() throws IOException; //如果底层资源对应的一个文件,该方法返回对应的File对象 File getFile() throws IOException; //返回当前Resource代表的底层文件资源的长度,一般是值代表的文件资源的长度。 long contentLength() throws IOException; //最后修改时间 long lastModified() throws IOException; //通过path 得到一个Resource对象 Resource createRelative(String relativePath) throws IOException; //获取资源名称 String getFilename(); //资源描述 String getDescription(); }
Resource在spring框架中起着不可或缺的作用,spring框架使用Resource装在各种资源,这些资源包括配置文件资源、国际化属性文件资源等。下面我们来了解一下Resource的具体实现类,如下图
1.ByteArrayResource:二进制数组表示的资源,二进制数组资源可以在内存中通过程序构造
2.ClassPathResource:类路径下的资源
3.FileSystemResource: 文件系统资源
4.InputStreamResource: 输入流返回表示资源
5.ServletContextResource: 基于web容器上下文资源
6.UrlResource: 对java.io.URL的封装,可以表示很多的协议的网络资源(http,ftp,文件系统资源)
有了这个抽象的资源类后,我们就可以将spring的配置信息放置在任何地方,只要最终可以通过Resource接口返回配置信息即可
7.PortletContextResource: 基于web容器上下文资源
8.DescriptiveResource:
假如有一个文件位于web应用的类路径下,用户可以通过以下方式对这个资源进行访问:
1.通过FileSystemResource以文件系统绝对路径的方式进行访问
2.通过ClassPathResource以类路径的方式进行访问
3.通过ServletContextResource以相对于Web应用根目录的方式进行访问
下面,我们分别通过FileSystemResource和ClassPathResource访问同一个文件资源:
package com.fortune.test.resource; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; import java.io.IOException; import java.io.InputStream; /** * Created with IntelliJ IDEA. * User: Alan * Date: 12-5-18 * Time: 上午10:58 */ public class FileSourceExample { public static void main(String args[]){ try{ String filePath ="D:/maskerSpring/chapter3/WebRoot/WEB-INF/classes/conf/file1.txt"; //①使用系统文件路径方式加载文件 Resource res1 = new FileSystemResource(filePath); //②使用类路径方式加载文件 Resource res2 = new ClassPathResource("/conf/file1.txt"); InputStream ins1 = res1.getInputStream(); InputStream ins2 = res2.getInputStream(); System.out.println("res1:"+res1.getFilename()); System.out.println("res2:"+res2.getFilename()); }catch (IOException e){ e.printStackTrace(); } } }
在获得资源后,用户就可以通过Resource接口定义的多个方法访问文件的数据和其它的信息:
如可以通过getFileName()直接获取文件的输入流。此外,还可以通过createRelative(String relativePath)在资源相对地址上创建新的文件。
在Web应用中,用户还可以通过ServletContextResource以相对于Web应用根目录的方式访问文件资源,如下所示:
<%@ page import="org.springframework.core.io.Resource" %> <%@ page import="org.springframework.web.context.support.ServletContextResource" %> <%@ page import="org.springframework.web.util.WebUtils" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <% //①注意文件资源地址以相对于Web应用根路径的方式表示 Resource res3 = new ServletContextResource(application,"/WEB-INF/classes/conf/file1.txt"); out.print(res3.getFilename()+"<br/>"); out.print(WebUtils.getTempDir(application).getAbsolutePath()); %>
对于位于远程服务器(Web服务器或FTP服务器)的文件资源,用户可以方便地通过UrlResource进行访问。
资源加载时默认采用系统编码读取资源内容,如果资源文件采用特殊的编码格式,那么可以通过EncodedResource对资源进行编码,以保证资源内容操作的正确性:
package com.fortune.test.resource; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.core.io.support.EncodedResource; import org.springframework.util.FileCopyUtils; /** * Created with IntelliJ IDEA. * User: Alan * Date: 12-5-18 * Time: 下午12:15 */ public class EncodedResourceExample { public static void main(String args[]) throws Throwable { Resource res = new ClassPathResource("conf/file1.txt"); EncodedResource encRes = new EncodedResource(res, "UTF-8"); String content = FileCopyUtils.copyToString(encRes.getReader()); System.out.println(content); } }